Top level methods are becoming singleton method as well as instance method - Why?

Hi,

If you look at the below example, you can see top level methods becoming singleton method as well as instance method. Why both ?. It should be only a private instance method of Object, I think.

arup~$ irb

def a; 10 ;end

=> :a

Object.a

NoMethodError: private method `a' called for Object:Class
from (irb):2
from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'

Object.send(:a)

=> 10

Object.new.a

NoMethodError: private method `a' called for #<Object:0x007f8c5a150430>
from (irb):4
from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'

Object.new.send(:a)

=> 10

Regards,
Arup Rakshit

If you look at the below example, you can see top level methods becoming
singleton method as well as instance method. Why both ?. It should be only a
private instance method of Object, I think.

It is: you can see this here:

$ ruby -e 'def foo;end;p self, method(:foo),
Object.instance_method(:foo), singleton_class.instance_method(:foo)'
main
#<Method: Object#foo>
#<UnboundMethod: Object#foo>
#<UnboundMethod: Object#foo>

As you can see, there is no singleton method in main which is the top
level object. Instead it's inherited from Object.

$ ruby -e 'def foo;end;p singleton_class.instance_method(:foo).owner'
Object

arup~$ irb

def a; 10 ;end

=> :a

Object.a

NoMethodError: private method `a' called for Object:Class
from (irb):2
from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'

Object.send(:a)

=> 10

Object.new.a

NoMethodError: private method `a' called for #<Object:0x007f8c5a150430>
from (irb):4
from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'

Object.new.send(:a)

=> 10

Your test does not prove anything about a singleton method because it
does not show where the method is defined.

Kind regards

robert

···

On Fri, Nov 7, 2014 at 9:14 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

> arup~$ irb
>
>>> def a; 10 ;end
>
> => :a
>
>>> Object.a
>
> NoMethodError: private method `a' called for Object:Class
> from (irb):2
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.send(:a)
>
> => 10
>
>>> Object.new.a
>
> NoMethodError: private method `a' called for #<Object:0x007f8c5a150430>
> from (irb):4
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.new.send(:a)
>
> => 10

Your test does not prove anything about a singleton method because it
does not show where the method is defined.

Kind regards

robert

What I meant to say, is, Why I am able to call a method on Object as well as
Object.new. Generally,

arup@linux-wzza:~> irb

class Foo
  def bar
    12
    end
  end

=> nil

Foo.bar

NoMethodError: undefined method `bar' for Foo:Class
        from (irb):6
        from /home/arup/.rvm/rubies/ruby-2.0.0-p451/bin/irb:12:in `<main>'

Foo.new.bar

=> 12

Here `bar` is an instance method of Foo, that's why Foo.bar didn't work.
Pretty clear, but Foo.new.bar work.

But in case main posted example, Object.new.a and Object.a both work. Which
made me confused. I don't know why...

···

--

Regards,
Arup Rakshit

Debugging is twice as hard as writing the code in the first place. Therefore,
if you write the code as cleverly as possible, you are, by definition, not
smart enough to debug it.

--Brian Kernighan

Apparently the last message did not go to the list.

···

---------- Forwarded message ----------
From: Robert Klemme <shortcutter@googlemail.com>
Date: Fri, Nov 7, 2014 at 10:48 PM
Subject: Re: Top level methods are becoming singleton method as well
as instance method - Why ?
To: Arup Rakshit

On Fri, Nov 7, 2014 at 6:24 PM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

$ ruby -e 'def foo;end;p singleton_class.instance_method(:foo).owner'
Object

> arup~$ irb
>
>>> def a; 10 ;end
>
> => :a
>
>>> Object.a
>
> NoMethodError: private method `a' called for Object:Class
> from (irb):2
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.send(:a)
>
> => 10
>
>>> Object.new.a
>
> NoMethodError: private method `a' called for #<Object:0x007f8c5a150430>
> from (irb):4
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.new.send(:a)
>
> => 10

Your test does not prove anything about a singleton method because it
does not show where the method is defined.

What I meant to say, is, Why I am able to call a method on Object as well as
Object.new. Generally,

arup@linux-wzza:~> irb

class Foo
  def bar
    12
    end
  end

=> nil

Foo.bar

NoMethodError: undefined method `bar' for Foo:Class
        from (irb):6
        from /home/arup/.rvm/rubies/ruby-2.0.0-p451/bin/irb:12:in `<main>'

Foo.new.bar

=> 12

Here `bar` is an instance method of Foo, that's why Foo.bar didn't work.
Pretty clear, but Foo.new.bar work.

But in case main posted example, Object.new.a and Object.a both work. Which
made me confused. I don't know why... :frowning:

Because

$ ruby -e 'p self, self.class'
main
Object

and because

$ ruby -e 'def a;end;p method(:a)'
#<Method: Object#a>

and because

$ ruby -e 'p Object.singleton_class.ancestors'
[Class, Module, Object, Kernel, BasicObject]

In other words:

Object.new.a tries to invoke the instance method of Object. Easy.

Object.a invokes an instance method of singleton class of Object. That
singleton class inherits Object and thus all instance methods from
Object.

Yes, there is some self-referentiality. But one can get used to it.

Kind regards

robert

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Remember that Object is an instance of Class, which inherits from Object.

···

On 08/11/2014, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

> arup~$ irb
>
>>> def a; 10 ;end
>
> => :a
>
>>> Object.a
>
> NoMethodError: private method `a' called for Object:Class
> from (irb):2
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.send(:a)
>
> => 10
>
>>> Object.new.a
>
> NoMethodError: private method `a' called for #<Object:0x007f8c5a150430>
> from (irb):4
> from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `<main>'
>
>>> Object.new.send(:a)
>
> => 10

Your test does not prove anything about a singleton method because it
does not show where the method is defined.

Kind regards

robert

What I meant to say, is, Why I am able to call a method on Object as well as

Object.new. Generally,

arup@linux-wzza:~> irb

class Foo
  def bar
    12
    end
  end

=> nil

Foo.bar

NoMethodError: undefined method `bar' for Foo:Class
        from (irb):6
        from /home/arup/.rvm/rubies/ruby-2.0.0-p451/bin/irb:12:in `<main>'

Foo.new.bar

=> 12

Here `bar` is an instance method of Foo, that's why Foo.bar didn't work.
Pretty clear, but Foo.new.bar work.

But in case main posted example, Object.new.a and Object.a both work. Which

made me confused. I don't know why...

--

Regards,
Arup Rakshit

Debugging is twice as hard as writing the code in the first place.
Therefore,
if you write the code as cleverly as possible, you are, by definition, not
smart enough to debug it.

--Brian Kernighan

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/