Just for the sake of learning more about the Ruby object model, I've been doing some experiments, and the following behavior surprised me:
Let's say we have a class Test:
class Test;end
Then, we class_eval Test.class in order to add a method to the Test object:
Test.class.class_eval do
def foo
puts 'foo called!'
end
end
(equivalent to calling Test.class.send(:define_method,:foo) ... )
Then:
irb(main):076:0> Test.foo
=> foo called!
But sending foo to class also works:
irb(main):006:0> Test.class.foo
=> foo called!
I still can't figure out why, though. The Class' singleton_class doesn't contain it (the only possible explanation that came to my mind was that somehow the method was added to the Class' singleton class):
Test.class.singleton_methods
=> [:nesting, :constants]
How does the method lookup work in this case? Why does sending :foo to Test.class also calls the method ? Am I missing something ?
···
----
As a reference, I did the same thing with an instance of Test:
irb(main):001:0> class Test;end
=> nil
irb(main):002:0> _foo = Test.new
=> #<Test:0x007fa2c39e2f38>
irb(main):003:0> _foo.class.class_eval do
irb(main):004:1* def foo
irb(main):005:2> puts 'foo called!'
irb(main):006:2> end
irb(main):007:1> end
=> :foo
irb(main):008:0> _foo.foo
foo called!
=> nil
irb(main):009:0> _foo.class.foo
NoMethodError: undefined method `foo' for Test:Class
This worked the way I expected it to.
Thanks in advance!
--
Marcelo Serpa
Because Test.class == Class and Class.class == Class
It's kind of swirly.
class A
def foo()...;end
end
B.is_a? A # so B.foo works
C.is_a? A # so C.foo works
thus:
class Class
def foo()...;end
end
Test.is_a? Class # Test.foo works
Class.is_a? Class # Class.foo works
Matthew Kerwin
···
On Jan 29, 2014 2:31 PM, "Marcelo Serpa" <mlists@fullofcaffeine.com> wrote:
Just for the sake of learning more about the Ruby object model, I've
been doing some experiments, and the following behavior surprised me:
Let's say we have a class Test:
class Test;end
Then, we class_eval Test.class in order to add a method to the Test object:
Test.class.class_eval do
def foo
puts 'foo called!'
end
end
(equivalent to calling Test.class.send(:define_method,:foo) ... )
Then:
irb(main):076:0> Test.foo
=> foo called!
But sending foo to class also works:
irb(main):006:0> Test.class.foo
=> foo called!
I still can't figure out why, though. The Class' singleton_class doesn't
contain it (the only possible explanation that came to my mind was that
somehow the method was added to the Class' singleton class):
Test.class.singleton_methods
=> [:nesting, :constants]
How does the method lookup work in this case? Why does sending :foo to
Test.class also calls the method ? Am I missing something ?
----
As a reference, I did the same thing with an instance of Test:
irb(main):001:0> class Test;end
=> nil
irb(main):002:0> _foo = Test.new
=> #<Test:0x007fa2c39e2f38>
irb(main):003:0> _foo.class.class_eval do
irb(main):004:1* def foo
irb(main):005:2> puts 'foo called!'
irb(main):006:2> end
irb(main):007:1> end
=> :foo
irb(main):008:0> _foo.foo
foo called!
=> nil
irb(main):009:0> _foo.class.foo
NoMethodError: undefined method `foo' for Test:Class
This worked the way I expected it to.
Thanks in advance!
--
Marcelo Serpa
Yep! I just figured out that a few minutes before you sent the message! Eureka 
Thank you very much for taking the time to answer.
Cheers,
···
--
Marcelo Serpa
Sent with Sparrow (http://www.sparrowmailapp.com/?sig\)
On Wednesday, January 29, 2014 at 12:45 AM, Matthew Kerwin wrote:
Because Test.class == Class and Class.class == Class
It's kind of swirly.
class A
def foo()...;end
end
B.is_a? A # so B.foo works
C.is_a? A # so C.foo works
thus:
class Class
def foo()...;end
end
Test.is_a? Class # Test.foo works
Class.is_a? Class # Class.foo works
Matthew Kerwin
On Jan 29, 2014 2:31 PM, "Marcelo Serpa" <mlists@fullofcaffeine.com (mailto:mlists@fullofcaffeine.com)> wrote:
> Just for the sake of learning more about the Ruby object model, I've been doing some experiments, and the following behavior surprised me:
>
> Let's say we have a class Test:
>
> class Test;end
>
> Then, we class_eval Test.class in order to add a method to the Test object:
>
> Test.class.class_eval do
> def foo
> puts 'foo called!'
> end
> end
>
> (equivalent to calling Test.class.send(:define_method,:foo) ... )
>
> Then:
>
> irb(main):076:0> Test.foo
> => foo called!
>
> But sending foo to class also works:
>
> irb(main):006:0> Test.class.foo
> => foo called!
>
>
> I still can't figure out why, though. The Class' singleton_class doesn't contain it (the only possible explanation that came to my mind was that somehow the method was added to the Class' singleton class):
>
> Test.class.singleton_methods
> => [:nesting, :constants]
>
>
> How does the method lookup work in this case? Why does sending :foo to Test.class also calls the method ? Am I missing something ?
>
> ----
>
> As a reference, I did the same thing with an instance of Test:
>
> irb(main):001:0> class Test;end
> => nil
> irb(main):002:0> _foo = Test.new
> => #<Test:0x007fa2c39e2f38>
> irb(main):003:0> _foo.class.class_eval do
> irb(main):004:1* def foo
> irb(main):005:2> puts 'foo called!'
> irb(main):006:2> end
> irb(main):007:1> end
> => :foo
> irb(main):008:0> _foo.foo
> foo called!
> => nil
> irb(main):009:0> _foo.class.foo
> NoMethodError: undefined method `foo' for Test:Class
>
>
> This worked the way I expected it to.
>
> Thanks in advance!
>
> --
> Marcelo Serpa
>