On Friday, 6 July 2018 at 15:51:34 UTC, Michael wrote:
Also, yes, I am using the setter method to play around with the precision of the double values, and do some normalising.
While writing I realized that the following is even the case without the 'ref' parameter: The caller of the setter will still be able to change the content of your private data after you checked it for validity. Take following example:

    class A
    {
        private static string[] _disallowed = ["damn"];
        private string[int] _dict;

        // called before and after every member method call
        invariant
        {
            import std.algorithm : any, canFind;
            // don't allow _dict to contain any from _disallowed
             assert(!this._dict.byValue()
                    .any!((entry) => _disallowed.canFind(entry)));
        }

        @property dict(string[int] dict)
        {
             // checks ...
            this._dict = dict;
        }

        void check() {
            import std.stdio : writeln;
            writeln(this._dict);
        }
    }

    unittest
    {
        string[int] loc;
        auto a = new A();
        loc[1] = "hello john";
        a.dict = loc; // using the @property setter
        loc[1] = "damn";
        a.check;
    }

What might be safer is using 'opIndexAssign'

        void opIndexAssign(string value, int key)
        {
            import std.algorithm.searching : canFind;
            if (!_disallowed.canFind(value))
                this._dict[key] = value;
        }

and also duping the dictionary that is handed to the Agent

        @property dict(string[int] dict)
        {
             // checks ...
            this._dict = dict.dup;
        }

So you can call

        string[int] loc;
        auto a = new A();
        loc[1] = "hello john";
        a.dict = loc;
        a[1] = "damn";
        loc[1] = "damn";
        a.check;

without assigning bad values.



I always want it to access the setter method, but I had hoped that, given it's an associative array, that the creation of the object in create() would simply create it on the heap and I could pass back a reference. It seems that I was incorrect, as if I set create() to explicitly return a reference, it complains about returning a reference to a local variable. Any advice on the best way to pass it as a reference?

I suppose this might already answer your question:
https://forum.dlang.org/post/edrejkakhaylivlqj...@forum.dlang.org

Reply via email to