Passing a reference to a returned reference

Timoses timosesu at gmail.com
Fri Jul 6 16:24:03 UTC 2018


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/edrejkakhaylivlqjaqe@forum.dlang.org



More information about the Digitalmars-d-learn mailing list