self.puts?

Discussion in 'Ruby' started by Derek Chesterfield, Sep 24, 2005.

  1. 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?
    Derek Chesterfield, Sep 24, 2005
    #1
    1. Advertising

  2. Derek Chesterfield

    Stefan Lang Guest

    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?


    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
    Stefan Lang, Sep 24, 2005
    #2
    1. Advertising

  3. 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!
    Derek Chesterfield, Sep 24, 2005
    #3
  4. Derek Chesterfield <> 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!


    Note also that you can call private methods with send:

    self.send:)puts, "foo")

    Kind regards

    robert
    Robert Klemme, Sep 24, 2005
    #4
  5. 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
    Devin Mullins, Sep 24, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ralf W. Grosse-Kunstleve
    Replies:
    16
    Views:
    561
    Lonnie Princehouse
    Jul 11, 2005
  2. Ralf W. Grosse-Kunstleve
    Replies:
    18
    Views:
    582
    Bengt Richter
    Jul 11, 2005
  3. Ralf W. Grosse-Kunstleve
    Replies:
    2
    Views:
    390
    Dan Sommers
    Jul 12, 2005
  4. Michael Brooks
    Replies:
    22
    Views:
    396
    Rick DeNatale
    Mar 27, 2007
  5. Raj Singh
    Replies:
    4
    Views:
    135
    Ryan Ingram
    Jan 29, 2008
Loading...

Share This Page