Methods in Ruby: objects or not?

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


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.


In Ruby, methods and blocks are not, in and of themselves, native or first-class objects. However, they can very easily be wrapped in objects, such that it generally makes no difference.

But try out, and keep in mind the result of,

a = Object.method(:new).object_id
b = Object.method(:new).object_id
a == b
=> false

In Haskell, all values (including numbers as well as lambdas and functions) are first-class values. In every aspect of the language, they are all treated equivalently. This is not the case in Ruby, but it can be approximated.