On Friday, 6 July 2018 at 15:14:01 UTC, Michael wrote:
class Agent
{
    private
    {
        double[int] mDict;
    }

    // Setter: copy
    void beliefs(ref double[int] dict)
    {
        import std.stdio : writeln;
        writeln("Setter function.");
        this.mDict = dict;
    }

    // Getter
    auto ref beliefs()
    {
        return this.mDict;
    }
}

class Operator
{
    static auto ref create()
    {
        double[int] dict;
        dict[2] = 1.0;
        dict[1] = 0.0;
        return dict;
    }
}

Throw in a writeln statement in getter and be amazed : D

    class Agent
    {
        private
        {
            double[int] mDict;
        }

        // Setter: copy
        void beliefs(ref double[int] dict)
        {
            import std.stdio : writeln;
            writeln("Setter function.");
            this.mDict = dict;
        }

        // Getter
        auto ref beliefs()
        {
            writeln("getter");
            return this.mDict;
        }
    }

    class Operator
    {
        static auto ref create()
        {
            double[int] dict;
            dict[2] = 1.0;
            dict[1] = 0.0;
            return dict;
        }
    }

    unittest
    {
        import std.stdio : writeln;

        Agent a = new Agent();

        writeln("Statement 1");
        a.beliefs = Operator.create();
        writeln("Statement 2");
        assert(a.beliefs.keys.length == 2);

        writeln("Statement 3");
        writeln(a.beliefs);
    }

If you remove the ref then "Statement 1" will use the setter method. Otherwise it calls the "auto ref" function to get a reference of 'mDict' and assign it a value. Essentially

        // Getter
        auto ref beliefs()
        {
            return this.mDict;
        }

makes your "private" variable not private any more, since you are leaking a reference to it. So any program calling "a.beliefs" can get a reference to your private data and modify it.

My guess is that (if ref is removed from the setter) it serves as a @property function:
https://dlang.org/spec/function.html#property-functions
So this allows the function to work in a statement like:
a.beliefs = <Whatever>

And apparently it is prioritized over the "ref beliefs()" function.


I guess it is nicer to actually use the "setter" function, as it allows you to inspect what the private data will be assigned to and take appropriate measures, whereas with the "ref beliefs()" method the private data is open for any manipulation out of your control.

Reply via email to