Can you call private methods with explicit receivers?

My understanding is the answer is no, you can’t call private methods
with explicit receivers, even self. See

However, the following example seems to counter that.

class A
def m2
self.m1 = “hello”
self.m3
end

private

def m1=(value)
@m1 = value
puts “assigning #{value} to @m1
end

def m3
puts “inside m3”
end
end

A.new.m2

The output is:
assigning hello to @m1
/tmp/t.rb:4:in m2': private method m3’ called for #<A:0x007fc4b404e568
@m1=“hehe”> (NoMethodError)
from /tmp/t.rb:19:in `’

Why can m2 call self.m1= which is a private method?

$ ruby –v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.3.0]

Best,
Jingjing

2012/7/5 Jingjing D. [email protected]:

Why can m2 call self.m1= which is a private method?

Probably because it would be otherwise impossible (except for using
#send), as m1 = "hello" would have been local variable assignment
and not method call.

– Matma R.

Thanks Bartosz. That makes sense. I guess due to Ruby’s rich syntax it
has to make some exceptions like this one under certain circumstances.

BTW, I found the blog post below which talks about this exact problem.

http://pivotallabs.com/users/pjaros/blog/articles/1968-private-setters-in-ruby-what-to-do-

Bartosz Dziewoński wrote in post #1067565:

2012/7/5 Jingjing D. [email protected]:

Why can m2 call self.m1= which is a private method?

Probably because it would be otherwise impossible (except for using
#send), as m1 = "hello" would have been local variable assignment
and not method call.

– Matma R.

On Thu, Jul 5, 2012 at 6:16 PM, Jingjing D. [email protected]
wrote:

end
end
Picking up Bartosz Dziewoński’s reference to #send, also note this:

A.new.m2 rescue puts $!.inspect
A.new.m3 rescue puts $!.inspect
A.new.send(:m3) rescue puts $!.inspect

produces:

assigning hello to @m1
#<NoMethodError: private method m3' called for #<A:0x9ba3a0 @m1="hello">> #<NoMethodError: private method m3’ called for #<A:0x9b9ac0>>
inside m3