# Useful inconcistency in calling foo vs. foo= private methods

**URL:** <https://www.ruby-forum.com/t/useful-inconcistency-in-calling-foo-vs-foo-private-methods/96662>\
**Category:** Ruby\
**Created:** [June 30, 2006, 4:34pm UTC](https://www.ruby-forum.com/t/useful-inconcistency-in-calling-foo-vs-foo-private-methods/96662 "2006-06-30T16:34:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [June 30, 2006, 4:34pm UTC](https://www.ruby-forum.com/t/useful-inconcistency-in-calling-foo-vs-foo-private-methods/96662/1 "2006-06-30T16:34:43Z")

</div>

Hi

This is an interesting sort of useful gotcha I recently stumbled upon:

class Foo  
private

def bar  
p ‘#bar called’  
end  
def bar=(val)  
p ‘#bar= called’  
end  
end

irb(main):002:0\> foo = Foo.new  
irb(main):003:0\> foo.instance\_eval { self.bar }  
NoMethodError: private method `bar’ called for #Foo:0x2c85a68  
irb(main):004:0\> foo.instance\_eval { self.bar = 1 }  
“#bar= called”

Formally, the the last line should have thrown an exception as well;  
afaik private methods can’t by definition be called with an explicit  
receiver. It seems the assignment methods are exempt from this rule.  
This is actually useful, since it overrides the higher precendence of  
local variable assignment over method calls; if self.bar= didn’t work,  
I don’t see any way short of self.send to call the private #bar=.

Still I thought it might be worth mentioning.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [June 30, 2006, 4:48pm UTC](https://www.ruby-forum.com/t/useful-inconcistency-in-calling-foo-vs-foo-private-methods/96662/2 "2006-06-30T16:48:18Z")

</div>

On Fri, 30 Jun 2006, Alder G. wrote:

> def bar=(val)  
> Formally, the the last line should have thrown an exception as well;  
> afaik private methods can’t by definition be called with an explicit  
> receiver. It seems the assignment methods are exempt from this rule.  
> This is actually useful, since it overrides the higher precendence of  
> local variable assignment over method calls; if self.bar= didn’t work,  
> I don’t see any way short of self.send to call the private #bar=.

a useful idiom

class Foo  
private

```
 def bar *a
   if a.size == 0
     @bar
   else
     __send__'bar=', a.shift
   end
 end
 def bar= val
   @bar = val
 end

```

end

Foo.new.instance\_eval{ bar 42 }

it avoids the issue somewhat.

regards.

-a
