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
http://www.skorks.com/2010/04/ruby-access-control-are-private-and-protected-methods-only-a-guideline/

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 `<main>'

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

···

--
Posted via http://www.ruby-forum.com/.

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 Rex

···

2012/7/5 Jingjing Duan <lists@ruby-forum.com>:

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

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

···

On Thu, Jul 5, 2012 at 6:16 PM, Jingjing Duan <lists@ruby-forum.com> wrote:

My understanding is the answer is no, you can't call private methods
with explicit receivers, even self. See
Ruby Access Control – Are Private And Protected Methods Only A Guideline? - Skorks

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

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 Duan <lists@ruby-forum.com>:

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 Rex

--
Posted via http://www.ruby-forum.com/\.