dusty
6/29/2008 7:37:00 PM
On Jun 29, 3:19 pm, Stefano Crocco <stefano.cro...@alice.it> wrote:
> On Sunday 29 June 2008, dusty wrote:
>
>
>
> > I'm trying to understand the difference between implicitly and
> > explicitly calling a private method and am hoping someone could shed
> > some light on this for me.
>
> > class Tester
> > def public_hello_good
> > say_hello
> > end
> > def public_hello_bad
> > self.say_hello
> > end
> > private
> > def say_hello
> > "hello"
> > end
> > end
>
> > irb(main):001:0> require 'tester'
> > => true
> > irb(main):002:0> a = Tester.new
> > => #<Tester:0x8c294>
> > irb(main):003:0> a.public_hello_good
> > => "hello"
> > irb(main):004:0> a.public_hello_bad
> > NoMethodError: private method `say_hello' called for #<Tester:0x8c294>
> > from ./tester.rb:6:in `public_hello_bad'
> > from (irb):4
> > from :0
>
> > What I'm wondering is why does this not work when I call
> > self.say_hello, but does work when I call say_hello? Since self is
> > the receiver in both cases, it seems that they would both work.
>
> > Anyone have any insight that they'd be willing to share on why it
> > works like that?
>
> > Thanks
>
> It's at the same time quite simple and quite confusing. It's simple because
> the rule determining how a private method can be called is very short and
> clear: you can only call a private method using the implicit receiver. It's
> confusing because it seems natural to interpret the previous statement so that
> it reads: you can only call a private method if the receiver is equal (in the
> eql? sense) as the implicit receiver. However, this interpretation is wrong.
> The words "only using the implicit receiver" should be taken literaly: if a
> method is private, you can't call it using the dot notation
> (receiver.method_name), even when the implicit and the explicit receiver are
> the same thing.
>
> I hope this helps
>
> Stefano
Thanks for the response.
I did find that it does work with an explicit receiver on a setter.
In the case below, I can call the private hello= method, with
self.hello=. I know that is required to state that I'm not setting a
local variable, but instead calling a method. But, it did work, so
somewhere in the code it is reading that self and understanding what I
mean by it, then perhaps dropping it and following the rules for the
rest of it?
I guess I don't really need to know why, just understand that it is
what it is. Perhaps the why is outside my scope of understanding
right now anyway. But, I am still curious.
:)
class Tester
def public_hello_good
say_hello
end
def public_hello_bad
self.say_hello
end
def public_set_hello(hello)
self.hello = hello
end
def hello
@hello
end
private
def say_hello
"hello"
end
def hello=(hello)
@hello = hello
end
end
irb(main):022:0> a = Tester.new
=> #<Tester:0x53728>
irb(main):023:0> a.public_set_hello("asdf")
=> "asdf"
irb(main):024:0> a.hello
=> "asdf"