# Private lvalue methods unusable?

**URL:** <https://rubytalk.org/t/private-lvalue-methods-unusable/4573>\
**Category:** ruby-talk\
**Created:** [6 February 2003 23:35 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573 "2003-02-06T23:35:08Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steven\_Smolinski](https://avatars.discourse-cdn.com/v4/letter/s/dc4da7/32.png) [@Steven\_Smolinski](https://rubytalk.org/u/Steven_Smolinski)\
**Post date:** [6 February 2003 23:35 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/1 "2003-02-06T23:35:08Z")

</div>

I’m learning Ruby, and trying to grasp the non-declarative concept with  
some small difficulties. Specifically, I can’t use a private lvalue  
method the way I want. Please excuse me if this is a FAQ, but I  
couldn’t find it.

Let’s say I have a class with a private method, say:

private  
def dollars=(someDollars)  
@cents = someDollars \* 100  
end

And if I want to use this method from some other method in the class, I  
always create a local variable instead. I can’t prepend the method name  
with a receiver (“self”) because the method is private.

For exmaple, this assigns to a local variable instead of using the  
private method above:

public  
def fillWallet  
dollars = 100  
puts “Wow! You’ve got $” + dollars().to\_s  
end

How do I call a private lvalue method?

Steve

> **···**
>
> –  
> Steven Smolinski =\> [http://arbiter.ca/](http://arbiter.ca/)  
> GnuPG Public Key =\> [http://arbiter.ca/steves\_public\_key.txt](http://arbiter.ca/steves_public_key.txt)  
> =\> or email me with ‘auto-key’ in the subject.  
> Key Fingerprint =\> 08C8 6481 3A7B 2A1C 7C26 A5FC 1A1B 66AB F637 495D

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [7 February 2003 02:25 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/2 "2003-02-07T02:25:51Z")

</div>

Hmmm… so self.dollars = 100 doesn’t work, eh? Only answer I can  
think of is

self.send(:dollars=, 100)

Beautiful, isn’t it? 😉

Actually, a better answer came to mind. Make :dollars= protected  
instead of private. It works.

Gavin

> **···**
>
> On Friday, February 7, 2003, 10:35:08 AM, Steven wrote:
> 
> > Let’s say I have a class with a private method, say:
> 
> > private  
> > def dollars=(someDollars)  
> > @cents = someDollars \* 100  
> > end
> 
> > And if I want to use this method from some other method in the class, I  
> > always create a local variable instead. I can’t prepend the method name  
> > with a receiver (“self”) because the method is private.
> 
> > For exmaple, this assigns to a local variable instead of using the  
> > private method above:
> 
> > public  
> > def fillWallet  
> > dollars = 100  
> > puts “Wow! You’ve got $” + dollars().to\_s  
> > end
> 
> > How do I call a private lvalue method?

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [7 February 2003 03:53 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/3 "2003-02-07T03:53:14Z")

</div>

Hi,

> **···**
>
> In message “Private lvalue methods unusable?” on 03/02/07, Steven Smolinski [steven.smolinski@sympatico.ca](mailto:steven.smolinski@sympatico.ca) writes:
> 
> > How do I call a private lvalue method?
> 
> No way, except using “send”, e.g.
> 
> self.send(:dollars=, 100)
> 
> ```
> matz.
> 
> ```

---

<div class="post-metadata">

**Author:** ![Steven\_Smolinski](https://avatars.discourse-cdn.com/v4/letter/s/dc4da7/32.png) [@Steven\_Smolinski](https://rubytalk.org/u/Steven_Smolinski)\
**Post date:** [7 February 2003 02:55 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/4 "2003-02-07T02:55:40Z")

</div>

> > How do I call a private lvalue method?

> Hmmm… so self.dollars = 100 doesn’t work, eh? Only answer I can  
> think of is
> 
> self.send(:dollars=, 100)
> 
> Beautiful, isn’t it? 😉

It’s as ugly as sin, but it works as advertised. 🙂

> Actually, a better answer came to mind. Make :dollars= protected  
> instead of private. It works.

That works also, but it changes the spec. So does redefining the method  
signature, like so: def dollars(aNumber). That also works, but changes  
the spec.

I’ll just have to put this down as a “gotcha” and carry on. Is there a  
list of places Ruby doesn’t follow the least surprise principle?

Thanks for the help,  
Steve

> **···**
>
> Gavin Sinclair [gsinclair@soyabean.com.au](mailto:gsinclair@soyabean.com.au) wrote:
> 
> > On Friday, February 7, 2003, 10:35:08 AM, Steven wrote:  
> > –  
> > Steven Smolinski =\> [http://arbiter.ca/](http://arbiter.ca/)  
> > GnuPG Public Key =\> [Webnewswire | Leading newswire service](http://arbiter.ca/steves_public_key.txt)  
> > =\> or email me with ‘auto-key’ in the subject.  
> > Key Fingerprint =\> 08C8 6481 3A7B 2A1C 7C26 A5FC 1A1B 66AB F637 495D

---

<div class="post-metadata">

**Author:** ![Dmitri\_Colebatch](https://avatars.discourse-cdn.com/v4/letter/d/f1d935/32.png) [@Dmitri\_Colebatch](https://rubytalk.org/u/Dmitri_Colebatch)\
**Post date:** [7 February 2003 03:56 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/5 "2003-02-07T03:56:29Z")

</div>

I’m assuming there’s some good reason for this that isn’t apparent to (at  
least) me. Would someone care to enlighten me out of interest?

cheers  
dim

> **···**
>
> > In message “Private lvalue methods unusable?” \> on 03/02/07, Steven Smolinski [steven.smolinski@sympatico.ca](mailto:steven.smolinski@sympatico.ca) writes:
> > 
> > > How do I call a private lvalue method?
> > 
> > No way, except using “send”, e.g.
> > 
> > self.send(:dollars=, 100)
> > 
> > matz.

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [7 February 2003 03:05 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/6 "2003-02-07T03:05:21Z")

</div>

There’s a newcomers list that documents gotchas, but it doesn’t  
include this one. I’ve never seen it mentioned before, actually.

You listening, Bill? 😉

Gavin

> **···**
>
> On Friday, February 7, 2003, 1:55:40 PM, Steven wrote:
> 
> > That works also, but it changes the spec. So does redefining the method  
> > signature, like so: def dollars(aNumber). That also works, but changes  
> > the spec.
> 
> > I’ll just have to put this down as a “gotcha” and carry on. Is there a  
> > list of places Ruby doesn’t follow the least surprise principle?

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [7 February 2003 04:29 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/7 "2003-02-07T04:29:58Z")

</div>

Hi,

> **···**
>
> In message “Re: Private lvalue methods unusable?” on 03/02/07, “Dmitri Colebatch” [dim@colebatch.com](mailto:dim@colebatch.com) writes:
> 
> > > self.send(:dollars=, 100)
> > 
> > I’m assuming there’s some good reason for this that isn’t apparent to (at  
> > least) me. Would someone care to enlighten me out of interest?
> 
> “private” does mean “can only be called without explicit receiver”.  
> This is the reason.
> 
> ```
> matz.
> 
> ```

---

<div class="post-metadata">

**Author:** ![Steven\_Smolinski](https://avatars.discourse-cdn.com/v4/letter/s/dc4da7/32.png) [@Steven\_Smolinski](https://rubytalk.org/u/Steven_Smolinski)\
**Post date:** [7 February 2003 04:36 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/8 "2003-02-07T04:36:03Z")

</div>

Private methods can’t have an explicit receiver (i.e., you can’t do  
self.method on a private). Calling it directly looks like this:

dollars = 100

So a private lvalue method and assignment to a local variable have the  
exact same syntax. Which means ruby had to choose whether it should:

1. look for a method and raise an exception if there is none, or
2. create a local variable.

It appears ruby does (2).

I suppose there’s always (3), which is to look for a method first and  
create a local variable if there’s no method defined. But that’s some  
serious semantic gymnastics, and may make things worse rather than  
better. I don’t know enough about ruby to comment on that.

Steve

> **···**
>
> Dmitri Colebatch [dim@colebatch.com](mailto:dim@colebatch.com) wrote:
> 
> > > In message “Private lvalue methods unusable?” \>\> on 03/02/07, Steven Smolinski [steven.smolinski@sympatico.ca](mailto:steven.smolinski@sympatico.ca) writes:
> > > 
> > > > How do I call a private lvalue method?
> > > 
> > > No way, except using “send”, e.g.
> > > 
> > > self.send(:dollars=, 100)
> > 
> > I’m assuming there’s some good reason for this that isn’t apparent to  
> > (at least) me. Would someone care to enlighten me out of interest?
> 
> –  
> Steven Smolinski =\> [http://arbiter.ca/](http://arbiter.ca/)  
> GnuPG Public Key =\> [Webnewswire | Leading newswire service](http://arbiter.ca/steves_public_key.txt)  
> =\> or email me with ‘auto-key’ in the subject.  
> Key Fingerprint =\> 08C8 6481 3A7B 2A1C 7C26 A5FC 1A1B 66AB F637 495D

---

<div class="post-metadata">

**Author:** ![David\_Alan\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@David\_Alan\_Black1](https://rubytalk.org/u/David_Alan_Black1)\
**Post date:** [7 February 2003 10:35 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/9 "2003-02-07T10:35:55Z")

</div>

Hi –

> **···**
>
> On Fri, 7 Feb 2003, Steven Smolinski wrote:
> 
> > I’ll just have to put this down as a “gotcha” and carry on. Is there a  
> > list of places Ruby doesn’t follow the least surprise principle?
> 
> Only Matz can tell you, because POLS in Ruby is specifically defined  
> as POLS for Matz 🙂
> 
> David
> 
> –  
> David Alan Black  
> home: [dblack@candle.superlink.net](mailto:dblack@candle.superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![William\_Djaja\_Tjokro](https://avatars.discourse-cdn.com/v4/letter/w/c89c15/32.png) [@William\_Djaja\_Tjokro](https://rubytalk.org/u/William_Djaja_Tjokro)\
**Post date:** [7 February 2003 04:56 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/10 "2003-02-07T04:56:14Z")

</div>

Hi Gavin,

Are you sure this belongs in the newcomers list? I never use  
‘private’ either 🙂 (I just put all the “private” methods in the C part.)

Regards,

Bill

> **···**
>
> Gavin Sinclair [gsinclair@soyabean.com.au](mailto:gsinclair@soyabean.com.au) wrote:
> 
> > There’s a newcomers list that documents gotchas, but it doesn’t  
> > include this one. I’ve never seen it mentioned before, actually.
> 
> > You listening, Bill? 😉
> 
> > Gavin

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [7 February 2003 08:43 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/11 "2003-02-07T08:43:44Z")

</div>

Hi,

> > > self.send(:dollars=, 100)
> > 
> > I’m assuming there’s some good reason for this that isn’t apparent to (at  
> > least) me. Would someone care to enlighten me out of interest?
> 
> “private” does mean “can only be called without explicit receiver”.  
> This is the reason.

It it a bad idea to relax the restriction, “can only be called  
without explicit receiver or with `self’ receiver”?

class C  
private  
def x=(val)  
@x = val  
end  
public  
def set\_x(val)  
self.x = val # OK  
self  
end  
end

C.new.set\_x(1) # OK  
C.new.x = 1 # NG

> **···**
>
> At Fri, 7 Feb 2003 13:29:58 +0900, Yukihiro Matsumoto wrote:
> 
> –  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [7 February 2003 06:19 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/12 "2003-02-07T06:19:43Z")

</div>

Not sure, no, since this is the first time it has come up. It is  
surprising behaviour though.

After all, dollar= is supposed to be “just another method”, isn’t it?

Gavin

> **···**
>
> On Friday, February 7, 2003, 3:56:14 PM, William wrote:
> 
> > Gavin Sinclair [gsinclair@soyabean.com.au](mailto:gsinclair@soyabean.com.au) wrote:
> 
> > > There’s a newcomers list that documents gotchas, but it doesn’t  
> > > include this one. I’ve never seen it mentioned before, actually.
> 
> > > You listening, Bill? 😉
> 
> > > Gavin
> 
> > Hi Gavin,
> 
> > Are you sure this belongs in the newcomers list? I never use  
> > ‘private’ either 🙂 (I just put all the “private” methods in the C part.)

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [7 February 2003 09:00 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/13 "2003-02-07T09:00:35Z")

</div>

Hi,

> **···**
>
> In message “Re: Private lvalue methods unusable?” on 03/02/07, [nobu.nokada@softhome.net](mailto:nobu.nokada@softhome.net) [nobu.nokada@softhome.net](mailto:nobu.nokada@softhome.net) writes:
> 
> > > “private” does mean “can only be called without explicit receiver”.  
> > > This is the reason.
> > 
> > It it a bad idea to relax the restriction, “can only be called  
> > without explicit receiver or with `self’ receiver”?
> 
> Hmm, interesting. Let me consider this issue.
> 
> ```
> matz.
> 
> ```

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [7 February 2003 09:11 UTC](https://rubytalk.org/t/private-lvalue-methods-unusable/4573/14 "2003-02-07T09:11:44Z")

</div>

Hi,

> > > “private” does mean “can only be called without explicit receiver”.  
> > > This is the reason.
> > 
> > It it a bad idea to relax the restriction, “can only be called  
> > without explicit receiver or with `self’ receiver”?
> 
> Hmm, interesting. Let me consider this issue.

Forgot an example. Error if the receiver isn’t literally  
`self’, even if it actually equals self.

```
private :x=
def my
  self
end
def my_x(val)
  my.x = val	# NG
end

```

And patch.

Index: eval.c

> **···**
>
> # At Fri, 7 Feb 2003 18:00:35 +0900, Yukihiro Matsumoto wrote:
> 
> RCS file: /cvs/ruby/src/ruby/eval.c,v  
> retrieving revision 1.392  
> diff -u -2 -p -r1.392 eval.c  
> — eval.c 7 Feb 2003 06:30:18 -0000 1.392  
> +++ eval.c 7 Feb 2003 08:14:53 -0000  
> @@ -1924,6 +1924,7 @@ is\_defined(self, node, buf)  
> goto check\_bound;
> 
> - 
> 
> ```
> case NODE_CALL:
> case NODE_ATTRASGN:
> 
> ```
> 
> - if (node-\>nd\_recv == (NODE \*)1) goto check\_bound;
> - 
> 
> ```
> case NODE_CALL:
> 
> ```
> 
> PUSH\_TAG(PROT\_NONE);  
> if ((state = EXEC\_TAG()) == 0) {  
> @@ -2746,13 +2747,21 @@ rb\_eval(self, n)  
> VALUE recv;  
> int argc; VALUE _argv; /_ used in SETUP\_ARGS \*/
> - 
> 
> ```
> int scope;
> TMP_PROTECT;
> 
> BEGIN_CALLARGS;
> 
> ```
> 
> - 
> 
> ```
> recv = rb_eval(self, node->nd_recv);
> 
> ```
> 
> - 
> 
> ```
> if (node->nd_recv == (NODE *)1) {
> 
> ```
> 
> - 
> 
> ```
> recv = self;
> 
> ```
> 
> - 
> 
> ```
> scope = 1;
> 
> ```
> 
> - 
> 
> ```
> }
> 
> ```
> 
> - 
> 
> ```
> else {
> 
> ```
> 
> - 
> 
> ```
> recv = rb_eval(self, node->nd_recv);
> 
> ```
> 
> - 
> 
> ```
> scope = 0;
> 
> ```
> 
> - 
> 
> ```
> }
> SETUP_ARGS(node->nd_args);
> END_CALLARGS;
> 
> SET_CURRENT_SOURCE();
> 
> ```
> 
> - 
> 
> ```
> rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
> 
> ```
> 
> - 
> 
> ```
> rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope);
> result = argv[argc-1];
> 
> ```
> 
> }  
> @@ -4092,10 +4101,18 @@ assign(self, lhs, val, pcall)  
> {  
> VALUE recv;
> 
> - 
> 
> ```
> recv = rb_eval(self, lhs->nd_recv);
> 
> ```
> 
> - 
> 
> ```
> int scope;
> 
> ```
> 
> - 
> 
> ```
> if (lhs->nd_recv == (NODE *)1) {
> 
> ```
> 
> - 
> 
> ```
> recv = self;
> 
> ```
> 
> - 
> 
> ```
> scope = 1;
> 
> ```
> 
> - 
> 
> ```
> }
> 
> ```
> 
> - 
> 
> ```
> else {
> 
> ```
> 
> - 
> 
> ```
> recv = rb_eval(self, lhs->nd_recv);
> 
> ```
> 
> - 
> 
> ```
> scope = 0;
> 
> ```
> 
> - 
> 
> ```
> }
> if (!lhs->nd_args) {
> /* attr set */
> ruby_current_node = lhs;
> SET_CURRENT_SOURCE();
> 
> ```
> 
> - 
> 
> ```
> rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, 0);
> 
> ```
> 
> - 
> 
> ```
> rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope);
> }
> else {
> 
> ```
> 
> @@ -4108,5 +4125,5 @@ assign(self, lhs, val, pcall)  
> SET\_CURRENT\_SOURCE();  
> rb\_call(CLASS\_OF(recv), recv, lhs-\>nd\_mid,
> 
> - 
> 
> ```
> RARRAY(args)->len, RARRAY(args)->ptr, 0);
> 
> ```
> 
> - 
> 
> ```
> RARRAY(args)->len, RARRAY(args)->ptr, scope);
> }
> 
> ```
> 
> }  
> Index: parse.y  
> ===================================================================  
> RCS file: /cvs/ruby/src/ruby/parse.y,v  
> retrieving revision 1.254  
> diff -u -2 -p -r1.254 parse.y  
> — parse.y 5 Feb 2003 08:11:27 -0000 1.254  
> +++ parse.y 7 Feb 2003 08:17:19 -0000  
> @@ -1403,5 +1403,8 @@ primary : literal  
> \> primary\_value ‘[’ aref\_args ‘]’  
> {
> 
> - 
> 
> ```
> $$ = NEW_CALL($1, tAREF, $3);
> 
> ```
> 
> - 
> 
> ```
> if (nd_type($1) == NODE_SELF)
> 
> ```
> 
> - 
> 
> ```
> $$ = NEW_FCALL(tAREF, $3);
> 
> ```
> 
> - 
> 
> ```
> else
> 
> ```
> 
> - 
> 
> ```
> $$ = NEW_CALL($1, tAREF, $3);
> }
> > tLBRACK aref_args ']'
> 
> ```
> 
> @@ -4628,7 +4631,13 @@ call\_op(recv, id, narg, arg1)  
> if (narg == 1) {  
> value\_expr(arg1);
> 
> - arg1 = NEW\_LIST(arg1);
> - }
> - else {
> - arg1 = 0;  
> }
> 
> - return NEW\_CALL(recv, id, narg==1?NEW\_LIST(arg1):0);
> 
> - if (recv && nd\_type(recv) == NODE\_SELF)
> - return NEW\_FCALL(id, arg1);
> - return NEW\_CALL(recv, id, arg1);  
> }
> 
> @@ -4668,4 +4677,6 @@ match\_gen(node1, node2)  
> }
> 
> - if (node1 && nd\_type(node1) == NODE\_SELF)
> - return NEW\_FCALL(tMATCH, NEW\_LIST(node2));  
> return NEW\_CALL(node1, tMATCH, NEW\_LIST(node2));  
> }  
> @@ -4784,5 +4795,8 @@ aryset(recv, idx)  
> NODE \*recv, \*idx;  
> {
> 
> - value\_expr(recv);
> 
> - if (recv && nd\_type(recv) == NODE\_SELF)
> - recv = (NODE \*)1;
> - else
> - value\_expr(recv);  
> return NEW\_ATTRASGN(recv, tASET, idx);  
> }  
> @@ -4802,5 +4816,8 @@ attrset(recv, id)  
> ID id;  
> {
> 
> - value\_expr(recv);
> 
> - if (recv && nd\_type(recv) == NODE\_SELF)
> - recv = (NODE \*)1;
> - else
> - value\_expr(recv);  
> return NEW\_ATTRASGN(recv, rb\_id\_attrset(id), 0);  
> }  
> @@ -5318,4 +5335,5 @@ new\_call(r,m,a)  
> NODE \*a;  
> {
> - if (r && nd\_type(r) == NODE\_SELF) return new\_fcall(m, a);  
> if (a && nd\_type(a) == NODE\_BLOCK\_PASS) {  
> a-\>nd\_iter = NEW\_CALL(r,m,a-\>nd\_head);
> 
> –  
> Nobu Nakada
