Self.puts?

I am trying to convince myself that Ruby is fully OO [I'm not suggesting it isn't!].

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:

I am trying to convince myself that Ruby is fully OO [I'm not
suggesting it isn't!].

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?

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!

···

On 24 Sep 2005, at 12:47pm, Stefan Lang wrote:

On Saturday 24 September 2005 12:30, Derek Chesterfield wrote:

Stefan Lang wrote:

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

Note also that you can call private methods with send:

self.send(:puts, "foo")

Kind regards

    robert

···

Derek Chesterfield <dez@mac.com> wrote:

On 24 Sep 2005, at 12:47pm, Stefan Lang wrote:

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!