View mode: basic / threaded / horizontal-split · Log in · Help
October 31, 2012
getters and setters not an lvalue
In my current code I'd like to do something ala:

void main(){
		getsettest test=new getsettest();
		
		test.value+=1;
}

class getsettest{
	int myvalue;
	
	this(){
	}
	
	@property{
	
		int value(){
			return myvalue;
		}
		
		void value(int value){
			myvalue=value;
		}
	}
}

but this gives the following error:
test.d(4): Error: test.value() is not an lvalue

Is there a rationale behind this decision of not translating
test.value+=1 to test.value= test.value +1 ?
October 31, 2012
Re: getters and setters not an lvalue
maarten van damme:

> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?

I think it's a temporary limit, meant to be removed/fixed.

Bye,
bearophile
October 31, 2012
Re: getters and setters not an lvalue
Ok, looking forward to the fix :)

Btw, I have a foreach loop and in that foreach loop I want to decide
if the current element can stay and if not, I want to remove it. If
removing it yields an empty range in the foreach loop, it crashes.
What's the sane way to do this?
October 31, 2012
Re: getters and setters not an lvalue
On Wed, 31 Oct 2012 14:08:18 -0000, maarten van damme  
<maartenvd1994@gmail.com> wrote:

> Ok, looking forward to the fix :)
>
> Btw, I have a foreach loop and in that foreach loop I want to decide
> if the current element can stay and if not, I want to remove it. If
> removing it yields an empty range in the foreach loop, it crashes.
> What's the sane way to do this?

Altering the thing you're "foreach"ing over is generally frowned upon  
because it causes issues like this.  Ideally D would const-ify the thing  
you're foreaching inside the body of the foreach to prevent it.  Usually  
you end up using "for" and an index value instead.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
October 31, 2012
Re: getters and setters not an lvalue
On 2012-10-31 13:46, maarten van damme wrote:
> In my current code I'd like to do something ala:
>
> void main(){
> 		getsettest test=new getsettest();
> 		
> 		test.value+=1;
> }
>
> class getsettest{
> 	int myvalue;
> 	
> 	this(){
> 	}
> 	
> 	@property{
> 	
> 		int value(){
> 			return myvalue;
> 		}
> 		
> 		void value(int value){
> 			myvalue=value;
> 		}
> 	}
> }
>
> but this gives the following error:
> test.d(4): Error: test.value() is not an lvalue
>
> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?

I think we need implement property rewrite to properly handle this.

-- 
/Jacob Carlborg
October 31, 2012
Re: getters and setters not an lvalue
On Wednesday, 31 October 2012 at 12:46:12 UTC, maarten van damme
wrote:
> In my current code I'd like to do something ala:
>
> void main(){
> 		getsettest test=new getsettest();
> 		
> 		test.value+=1;
> }
>
> class getsettest{
> 	int myvalue;
> 	
> 	this(){
> 	}
> 	
> 	@property{
> 	
> 		int value(){
> 			return myvalue;
> 		}
> 		
> 		void value(int value){
> 			myvalue=value;
> 		}
> 	}
> }
>
> but this gives the following error:
> test.d(4): Error: test.value() is not an lvalue
>

You can make int value() to return by reference.
October 31, 2012
Re: getters and setters not an lvalue
On Wednesday, 31 October 2012 at 12:46:12 UTC, maarten van damme 
wrote:
> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?

Probably there were no such decision at all and you just ran into 
issue which has never worked. BTW properties are syntax construct 
which allows to omit braces when calling functions. You actually 
call value function which doesn't return value by reference.
October 31, 2012
Re: getters and setters not an lvalue
On Wednesday, 31 October 2012 at 12:46:12 UTC, maarten van damme 
wrote:
> In my current code I'd like to do something ala:
>
> void main(){
> 		getsettest test=new getsettest();
> 		
> 		test.value+=1;
> }
>
> class getsettest{
> 	int myvalue;
> 	
> 	this(){
> 	}
> 	
> 	@property{
> 	
> 		int value(){
> 			return myvalue;
> 		}
> 		
> 		void value(int value){
> 			myvalue=value;
> 		}
> 	}
> }
>
> but this gives the following error:
> test.d(4): Error: test.value() is not an lvalue
>
> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?

It's not that simple as "test.value" is not an LValue, so from 
the compiler's perspective "test.value = test.value + 1" calls 
two different functions, that may or may not have anything to do 
with each other.

The expansion "++ => +=1 => a = a + 1" works if there is only 1 
lvalue the whole chain through.

Can the compiler really assume it can do that? And is it a smart 
move to allow it to make that assumption. What you have there is 
basically an encapsulated field, that does not leak its address:

You can take the filed, you can update it with a new value, but 
you can't modify it.

If you allow "test.value+=1", then where does it end?

Is this legal?
//----
void foo(int& a) {...}
foo(test.value);
//----

Would you want the compiler to expand it into:
//----
void foo(int& a) {...}

//scope for __temp
{
  auto __temp = test.value;
  foo(temp);
  test.value = temp;
}
//----

--------------------
IMO, if you take the time to write both functions, instead of 
just:
//----
@property ref int front(){return myvalue;}
//----
Then the compiler must assume you did it for a reason, and not 
mess with your code.
October 31, 2012
Re: getters and setters not an lvalue
Ok, makes sense now :)

2012/10/31 monarch_dodra <monarchdodra@gmail.com>:
> On Wednesday, 31 October 2012 at 12:46:12 UTC, maarten van damme wrote:
>>
>> In my current code I'd like to do something ala:
>>
>> void main(){
>>                 getsettest test=new getsettest();
>>
>>                 test.value+=1;
>> }
>>
>> class getsettest{
>>         int myvalue;
>>
>>         this(){
>>         }
>>
>>         @property{
>>
>>                 int value(){
>>                         return myvalue;
>>                 }
>>
>>                 void value(int value){
>>                         myvalue=value;
>>                 }
>>         }
>> }
>>
>> but this gives the following error:
>> test.d(4): Error: test.value() is not an lvalue
>>
>> Is there a rationale behind this decision of not translating
>> test.value+=1 to test.value= test.value +1 ?
>
>
> It's not that simple as "test.value" is not an LValue, so from the
> compiler's perspective "test.value = test.value + 1" calls two different
> functions, that may or may not have anything to do with each other.
>
> The expansion "++ => +=1 => a = a + 1" works if there is only 1 lvalue the
> whole chain through.
>
> Can the compiler really assume it can do that? And is it a smart move to
> allow it to make that assumption. What you have there is basically an
> encapsulated field, that does not leak its address:
>
> You can take the filed, you can update it with a new value, but you can't
> modify it.
>
> If you allow "test.value+=1", then where does it end?
>
> Is this legal?
> //----
> void foo(int& a) {...}
> foo(test.value);
> //----
>
> Would you want the compiler to expand it into:
> //----
> void foo(int& a) {...}
>
> //scope for __temp
> {
>   auto __temp = test.value;
>   foo(temp);
>   test.value = temp;
> }
> //----
>
> --------------------
> IMO, if you take the time to write both functions, instead of just:
> //----
> @property ref int front(){return myvalue;}
> //----
> Then the compiler must assume you did it for a reason, and not mess with
> your code.
October 31, 2012
Re: getters and setters not an lvalue
> but this gives the following error:
> test.d(4): Error: test.value() is not an lvalue
>
> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?

http://forum.dlang.org/thread/xcbweciovapinaicxgbn@forum.dlang.org

and

http://d.puremagic.com/issues/show_bug.cgi?id=8006
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home