Thread overview
property += operator
May 10, 2018
SrMordred
May 10, 2018
Dlang User
May 10, 2018
SrMordred
May 10, 2018
Dlang User
May 10, 2018
Ali Çehreli
May 10, 2018
Dlang User
May 10, 2018
Jonathan M Davis
May 10, 2018
Mike Franklin
May 10, 2018
struct T
{
    int x;
    @property ref X(){ return x; }
    @property X(int v)
    {
        x = v;
    }
}

T t;
t.X += 10;

The setter 'x = v' are not executed because i´m returning the reference of x.
And without the 'ref' the compiler complains because 'x' is not a lvalue.

Any solution to make it work like native arr.length+=10 works?

( I Thought on returning a struct with "+=" operator but it is a strange solution )
May 10, 2018
On 5/10/2018 1:43 PM, SrMordred wrote:
> struct T
> {
>      int x;
>      @property ref X(){ return x; }
>      @property X(int v)
>      {
>          x = v;
>      }
> }
> 
> T t;
> t.X += 10;
> 
> The setter 'x = v' are not executed because i´m returning the reference of x.
> And without the 'ref' the compiler complains because 'x' is not a lvalue.
> 
> Any solution to make it work like native arr.length+=10 works?
> 
> ( I Thought on returning a struct with "+=" operator but it is a strange solution )

I am relatively new to D and I was under the impression that that was a limitation of @property functions.

But, re-reading the language reference, it gave this example (it returns something from the write property, which seems odd), I modified to add refs, and then it seems to work, but I am not sure if it is correct or not:

import std.stdio;

struct Foo
{
    @property ref int data() { return m_data; } // read property

    @property ref int data(int value) { return m_data = value; } // write property

  private:
    int m_data;
}

void main()
{
	Foo f;
	f.data = 5;
	f.data++;
	f.data+= 2;
	writeln(f.data);
	
}

May 10, 2018
On Thursday, 10 May 2018 at 19:41:41 UTC, Dlang User wrote:
> On 5/10/2018 1:43 PM, SrMordred wrote:
>> [...]
>
> I am relatively new to D and I was under the impression that that was a limitation of @property functions.
>
> But, re-reading the language reference, it gave this example (it returns something from the write property, which seems odd), I modified to add refs, and then it seems to work, but I am not sure if it is correct or not:
>
> import std.stdio;
>
> struct Foo
> {
>     @property ref int data() { return m_data; } // read property
>
>     @property ref int data(int value) { return m_data = value; } // write property
>
>   private:
>     int m_data;
> }
>
> void main()
> {
> 	Foo f;
> 	f.data = 5;
> 	f.data++;
> 	f.data+= 2;
> 	writeln(f.data);
> 	
> }

this didn´t work either.
note that 'f.data+= 2;' don't call the write property
May 10, 2018
On 5/10/2018 2:50 PM, SrMordred wrote:
> On Thursday, 10 May 2018 at 19:41:41 UTC, Dlang User wrote:
>> On 5/10/2018 1:43 PM, SrMordred wrote:
>>> [...]
>>
>> I am relatively new to D and I was under the impression that that was a limitation of @property functions.
>>
>> But, re-reading the language reference, it gave this example (it returns something from the write property, which seems odd), I modified to add refs, and then it seems to work, but I am not sure if it is correct or not:
>>
>> import std.stdio;
>>
>> struct Foo
>> {
>>     @property ref int data() { return m_data; } // read property
>>
>>     @property ref int data(int value) { return m_data = value; } // write property
>>
>>   private:
>>     int m_data;
>> }
>>
>> void main()
>> {
>>     Foo f;
>>     f.data = 5;
>>     f.data++;
>>     f.data+= 2;
>>     writeln(f.data);
>>
>> }
> 
> this didn´t work either.
> note that 'f.data+= 2;' don't call the write property

That's odd, it works on my machine (Windows 10 with V2.079.0 DMD compiler).

I changed main to this:

void main()
{
	Foo f;
	writeln(f.data);
	f.data = 5;
	writeln(f.data);
	f.data++;
	writeln(f.data);
	f.data+= 2;
	writeln(f.data);	
}


and then I get this output:

0
5
6
8

May 10, 2018
On 05/10/2018 01:03 PM, Dlang User wrote:

>> this didn´t work either.
>> note that 'f.data+= 2;' don't call the write property
>
> That's odd, it works on my machine (Windows 10 with V2.079.0 DMD compiler).

Try putting writeln expressions in the two functions to see which one gets called. ;)

Ali

May 10, 2018
On 5/10/2018 3:18 PM, Ali Çehreli wrote:
> On 05/10/2018 01:03 PM, Dlang User wrote:
> 
>  >> this didn´t work either.
>  >> note that 'f.data+= 2;' don't call the write property
>  >
>  > That's odd, it works on my machine (Windows 10 with V2.079.0 DMD compiler).
> 
> Try putting writeln expressions in the two functions to see which one gets called. ;)
> 
> Ali
> 

Now, I see the problem. Sorry for the noise.


May 10, 2018
On Thursday, May 10, 2018 18:43:40 SrMordred via Digitalmars-d-learn wrote:
> struct T
> {
>      int x;
>      @property ref X(){ return x; }
>      @property X(int v)
>      {
>          x = v;
>      }
> }
>
> T t;
> t.X += 10;
>
> The setter 'x = v' are not executed because i´m returning the
> reference of x.
> And without the 'ref' the compiler complains because 'x' is not a
> lvalue.
>
> Any solution to make it work like native arr.length+=10 works?
>
> ( I Thought on returning a struct with "+=" operator but it is a
> strange solution )

Just in general, I would suggest that you not provide both a getter and a setter if the getter returns by ref. If that's what you're doing, then just use the getter as the setter. In general though, with getters and setters, you can only get and set a value. Stuff like += won't work unless you return by ref (which frequently makes having a function instead of just making the variable public kind of pointless) or if you play games like returning an object that overrides opOpAssign!"+" which gets kind of weird and complicated, albeit sometimes reasonable and useful.

IIRC, there's a DIP for trying to make += work with just getters and setters, but I don't know if we're ever going to see anything like it in the language.

- Jonathan M Davis


May 10, 2018
On Thursday, 10 May 2018 at 21:16:12 UTC, Jonathan M Davis wrote:

> IIRC, there's a DIP for trying to make += work with just getters and setters, but I don't know if we're ever going to see anything like it in the language.

Yes, the DIP is here:  https://github.com/dlang/DIPs/pull/97

It's currently stalled while I elaborate on the merits, or lack thereof, of a library solution.  The best library implementation I've seen is https://forum.dlang.org/post/mqveusvzkmkshrzwsgjy@forum.dlang.org

I'm exploring the idea of continuing with the DIP, or adding features (or removing limitations of the language) to make a library implementation more appealing.  IMO, it'd be great if we could add more composable primitives to the language, and get rid of quirky features like @property.

Mike