So writing 'object.method' sends a message 'method' to 'object', and
writing 'method' implies sending to self. So how come the result of
'puts' is different to the result of 'self.puts'?
> $ irb
> irb(main):001:0> puts "hello"
> hello
> => nil
> irb(main):002:0> self.puts "hello"
> NoMethodError: private method `puts' called for main:Object
> from (irb):2
I'm sure this is a semantic question, but I can't figure it out! How
come 'self.puts' find the private puts method of Object, whereas
'puts' finds Kernel.puts?
Both find the private method "puts", which is defined in the
Kernel module. The Kernel module is included in the Object class.
Ruby doesn't allow that a private method is called with an explicit
receiver. If you write "self.puts", "self" is an explicit receiver.
If you simply write "puts" the receiver is implicitly "self".
Also try:
$irb
irb(main):001:0> class A
irb(main):002:1> def foo
irb(main):003:2> puts "hello, this is the foo method"
irb(main):004:2> bar
irb(main):005:2> self.bar
irb(main):006:2> end
irb(main):007:1> private
irb(main):008:1> def bar
irb(main):009:2> puts "hello, this is the bar method"
irb(main):010:2> end
irb(main):011:1> end
=> nil
irb(main):012:0> a = A.new
=> #<A:0x402e30fc>
irb(main):013:0> a.bar
NoMethodError: private method `bar' called for #<A:0x402e30fc>
from (irb):13
irb(main):014:0> a.foo
hello, this is the foo method
hello, this is the bar method
NoMethodError: private method `bar' called for #<A:0x402e30fc>
from (irb):5:in `foo'
from (irb):14
HTH,
Stefan
> On Saturday 24 September 2005 12:30, Derek Chesterfield wrote:
>
>> how come the
>> result of 'puts' is different to the result of 'self.puts'?
>
> Ruby doesn't allow that a private method is called with an explicit
> receiver. If you write "self.puts", "self" is an explicit receiver.
> If you simply write "puts" the receiver is implicitly "self".
Ah - I knew it was semantics! Thanks for your explanation. It makes
perfect sense now: because it is a private method, you *shouldn't*
need to write it explicitly! This code also solidified it for me:
> $ irb
> irb(main):001:0> module Kernel
> irb(main):002:1> public :puts
> irb(main):003:1> end
> => Kernel
> irb(main):004:0> puts "asd"
> asd
> => nil
> irb(main):005:0> self.puts "asd"
> asd
> => nil
Thanks again!
Note also that you can call private methods with send:
self.send(:puts, "foo")
Kind regards
robert
>Both find the private method "puts", which is defined in the
>Kernel module. The Kernel module is included in the Object class.
>
>Ruby doesn't allow that a private method is called with an explicit
>receiver. If you write "self.puts", "self" is an explicit receiver.
>If you simply write "puts" the receiver is implicitly "self".
>
>
There's one exception to this rule, which'll probably kick you in the
pants somewhere down the line if you're not aware of it:
irb(main):001:0> class Moo
irb(main):002:1> private
irb(main):003:1> def loorg=(fun_size)
irb(main):004:2> end
irb(main):005:1> public
irb(main):006:1> def tooop
irb(main):007:2> self.loorg = 5
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> pants = Moo.new
=> #<Moo:0x2cf40e0>
irb(main):011:0> pants.tooop
=> 5
irb(main):012:0> pants.loorg = 5
NoMethodError: private method `loorg=' called for #<Moo:0x2cf40e0>
from (irb):12
irb(main):013:0>
That is, "self." is not considered an explicit receiver if the method
name ends in a "=". That's because "loorg = 5" would just set a local
variable, so the Ruby way to call the "loorg=" method is to use "self.".
devin