[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

implicit vs explicit self in private methods

dusty

6/29/2008 7:11:00 PM

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
3 Answers

Stefano Crocco

6/29/2008 7:20:00 PM

0

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


David A. Black

6/29/2008 7:22:00 PM

0

Hi --

On Mon, 30 Jun 2008, Stefano Crocco 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.

Unless it ends in = :-)


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.r... for details and updates!

dusty

6/29/2008 7:37:00 PM

0

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"