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

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

Object.new.send(:a)
=> 10

Regards,
Arup R.

On Fri, Nov 7, 2014 at 9:14 AM, Arup R.
[email protected] wrote:

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

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

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

from /Users/shreyas/.rvm/rubies/ruby-2.1.4/bin/irb:11:in `’

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,

[email protected]:~> 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

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

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

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

Nope, it only defines private method of Object class:

irb> def a;10;end
=> :a
irb> method(:a)
=> #<Method: Object#a>
^^^^^^^^
irb> self.class # we have open the Object class in irb
=> Object
irb> singleton_methods.grep :a
=> []
irb> self.class.singleton_methods.grep :a # equivalent to previous call
=> []
irb> private_methods.grep :a
=> [:a]
irb> self.class.private_methods.grep :a # equivalent to previous call
=> [:a]

irb> ‘huh’.send :a # if defined at Object it’s indeed accessible
everywhere
=> 10

If you’d need to define a singleton method in a similar way (at the top
level), it need to be qualified as usual:
irb> def self.aa;123;end
=> :aa
irb> method(:aa)
=> #<Method: main.aa>
^^^^^^^
irb> singleton_methods.grep :aa
=> [:aa]
private_methods.grep :aa
=> []
irb> ‘huh’.send :aa # has to accessible only from main' NoMethodError: undefined methodaa’ for “huh”:String
irb> self.aa
=> 123
irb> singleton_method(:aa).call # equivalent to previous call
=> 123

Yes, send() overpass the rules. send() is good for unit test, when you
want to test private methods. Cheers.