Methods in Ruby: objects or not?

You can't really tell.

The only way to get access to a method is to send the #method message to some object, which will then return a Method object. But is that Method object the method itself? Or is it a wrapper around the method? Or is it a converted version of the original method?

You can't know: if you want to look at a method, you have to call #method, at which point you definitely will get an object. What it was before you called #method you can't look at, therefore you can't tell.

A couple of datapoints: in Ruby, everything returns a value. What does def return? It always returns nil, not a Method object. And define_method? It returns a Proc, but not a Method (nor an UnboundMethod). [Note: in Rubinius, def returns the compiled bytecode of the method, but still not a Method object.]

If you look at the 4th and 5th paragraphs of Section 6.1 of the Ruby Language Specification (lines 29-34 and 1-5 on pages 5 and 6), you can clearly see that there is a distinction drawn between methods and objects. And if you look at the specification of the builtin classes, you will find that neither Method nor UnboundMethod are in there, nor is Object#method. IOW: you can build a perfectly standards-compliant Ruby interpreter in which methods aren't objects.

Now, blocks OTOH definitely aren't objects. There are many ways to construct Proc objects from blocks, which then have the same behavior as the original block (lambda, proc, Proc.new, the & sigil), but blocks themselves aren't objects.

Think about it this way: you can pass a string to File.new to construct a file object, but that doesn't make a string a file. You can pass a block to Proc.new to construct a proc object, but that doesn't make a block a proc.


Methods are a fundamental part of Ruby's syntax, but they are not values that Ruby programs can operate on. That is, Ruby's methods are not objects in the way that strings, numbers, and arrays are. It is possible, however, to obtain a Method object that represents a given method, and we can invoke methods indirectly through Method objects.

From The Ruby Programming Language:
alt text