www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - AA value returned by ref function (comments needed)

reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
In the 9498 issue there is a discussion about such code:

string[string] myValues;

ref string getValue(string v) {
    return myValues[v];
}

void main() {
    getValue("myValue") = "myString";
}

Currently it throws range violation as myValues[v] is regarged as 
rvalue (in Andrei's notion it is a read operation).

On the one hand, returning some value from AA array is a read 
operation which should throw as it happens with non-ref function. 
It is also impossible to know whether some new value would be 
assigned or just be copied like this:

string s = getValue(); // obviously read operation which need 
throw.
tl;dr it does not really matter how value is returned, only 
whether is exists or not.

On the other hand, as original code shows, it could be write 
operation, so function should not throw.

Spec is silent about this and TDPL barely discusses it, let alone 
ref corner case.

Thoughts?

http://d.puremagic.com/issues/show_bug.cgi?id=9498
Jun 30 2013
next sibling parent "Diggory" <diggsey googlemail.com> writes:
On Sunday, 30 June 2013 at 09:46:00 UTC, Maxim Fomin wrote:
 In the 9498 issue there is a discussion about such code:

 string[string] myValues;

 ref string getValue(string v) {
    return myValues[v];
 }

 void main() {
    getValue("myValue") = "myString";
 }

 Currently it throws range violation as myValues[v] is regarged 
 as rvalue (in Andrei's notion it is a read operation).

 On the one hand, returning some value from AA array is a read 
 operation which should throw as it happens with non-ref 
 function. It is also impossible to know whether some new value 
 would be assigned or just be copied like this:

 string s = getValue(); // obviously read operation which need 
 throw.
 tl;dr it does not really matter how value is returned, only 
 whether is exists or not.

 On the other hand, as original code shows, it could be write 
 operation, so function should not throw.

 Spec is silent about this and TDPL barely discusses it, let 
 alone ref corner case.

 Thoughts?

 http://d.puremagic.com/issues/show_bug.cgi?id=9498

As you said, associative arrays are accessed through read or write operations, they do not return by ref. This is done using a simple rewrite rule replacing assignment with a call to the setter, and it is the container (the associative array) which implements "opSliceAssign" operation, so it is only when accessing that container that the rewrite should occur. If assignment of the return type is wanted, it can be achieved by returning a type which implements "opAssign" which then does the write operation.
Jun 30 2013
prev sibling parent "w0rp" <devw0rp gmail.com> writes:
Hmm, I would just write two overloads, one reading, one writing, 
and stop there. I usually do this for slices too, so one can be 
const and the other non-const. I assume the want to do this 
usually appears in member functions in structs and classes.
Jun 30 2013