self.puts?

D

Derek Chesterfield

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?
 
S

Stefan Lang

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
 
D

Derek Chesterfield

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!
 
R

Robert Klemme

Derek Chesterfield said:
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:


Thanks again!

Note also that you can call private methods with send:

self.send:)puts, "foo")

Kind regards

robert
 
D

Devin Mullins

Stefan said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top