Everything is an object... right?

Hello,

So everything in Ruby is an object, right? Classes are objects, etc. And
methods are objects, right?

My question: when I define a method, is a method object created right then?
Or is a method object only created when I call Object#method? If so,
objects of class Method really methods, or are they just objects associated
with those methods?

If I redefine a method, does that change the original method object or make
a new one?

Chris

Hello,

So everything in Ruby is an object, right? Classes are objects, etc. And
methods are objects, right?

I think it would be more correct to say that all data in Ruby are
objects.

For example, “if” and other control structures are not objects. The
stack is not an object.

My question: when I define a method, is a method object created right then?

A method is created (and a Node that holds that method), but a Method
object is not created.

Or is a method object only created when I call Object#method? If so,

Yes.

objects of class Method really methods, or are they just objects associated
with those methods?

They are callable objects (that is, they respond to the call() method).

If I redefine a method, does that change the original method object or make
a new one?

If you redefine a method, the old method is replaced with the new one.
But anyone who still has a reference to the old method still refers to
the old method:

irb(main):001:0> class Foo; def foo; puts ‘foo!’; end; end
=> nil
irb(main):002:0> f = Foo.new
=> #Foo:0x40262d8c
irb(main):003:0> m = f.method(:foo)
=> #<Method: Foo(Foo)#foo>
irb(main):004:0> class Foo; def foo; puts ‘bar!’; end; end
=> nil
irb(main):005:0> m.call()
foo!
=> nil

Paul

···

On Tue, Feb 11, 2003 at 04:17:58AM +0900, Chris Pine wrote:

I’m not really sure why I didn’t just use irb in the first place… sorry.

Anyway, I mostly answered my own question. Just in case anyone else is
wondering:

The first thing to realize is that when you create an instance method, the
associated object would not be a Method, but an UnboundMethod. For example:

irb(main):001:0> class Foo
irb(main):002:1> def foo; ‘foo’; end
irb(main):003:1> end
=> nil
irb(main):004:0> Foo.instance_method(:foo)
=> #<UnboundMethod: Foo#foo>
irb(main):005:0> Foo.instance_method(:foo).id
=> 537250374
irb(main):006:0> Foo.instance_method(:foo).id
=> 537244984
irb(main):007:0> Foo.instance_method(:foo).id
=> 537202282

As you can see, I get back a different object each time, so the (unbound)
method itself is not really an object.

Same is true for bound methods:

irb(main):009:0> x = Foo.new
=> #Foo:0x400911cc
irb(main):010:0> x.method(:foo).id
=> 537158072
irb(main):011:0> x.method(:foo).id
=> 537149042

However, if I were to get an instance of Method or UnboundMethod (I don’t
want to call them “methods”, because they really aren’t methods, they are
objects associated with those methods), and then redefine the method they
associate with, they still refer to the original methods. So it’s almost
like they are real methods. In fact, if calling x.method(:foo).id' returned the same object each time (assumingfoo’ hadn’t been redefined),
they basically would be real methods, wouldn’t they? I mean, methods
would essentially be real objects. I think.

Well, I guess they still wouldn’t show up in ObjectSpace.each_object…
would they? Hmmm… Is there a reason they weren’t made real objects? It
seems like they came awfully close.

But now I have more questions…

First, is there a way to get the Method object for the method being
executed?

Second, why doesn’t this work?

irb(main):001:0> class Foo
irb(main):002:1> def foo; ‘foo’; end
irb(main):003:1> end
=> nil
irb(main):004:0> x = Foo.new
=> #Foo:0x400bc178
irb(main):005:0> def x.foo; ‘bar’; end
=> nil
irb(main):006:0> Foo.instance_method(:foo).bind(x)
TypeError: method foo' overridden from (irb):6:inbind’
from (irb):6

It works if I don’t define x.foo first.

Chris