1.method('+') is not the same as 1.+, so your example does not prove + is
a method. The object ID you get with 1.method('+').object_id is actually
the object ID of the object that is returned by the method "method" when
it is passed an argument of the string "+". That is not the same thing
as an object ID for the + method itself.
Here's a thought experiment for you:
If + is an object, and 1.method('+') returns that object so that you can
get its object ID with 1.method('+').object_id, this should work:
Fire up irb and try it, now. It doesn't work.
Instead, if you want to use it, you need to do this:
That's because a "method object" is not a method; it is a proc that wraps
the method and its scope context.
Why should you be able to do foo(3) ? That would require completely changin=
g
the way Ruby is interpreted. I suspect this idea comes from less OO
languages like JavaScript and Python. In Ruby, you can't do that, because i=
f
foo is the object, then you interact with it by invoking methods. (3) isn't
a method, it's an argument, so we need to define a method that will invoke
our method object. So we define #call and use .call(3)
The fact that you have to send it a message shows it is an object, which is
easy to see, since at this point, foo _is_ an object. It is an instance of
Method.
I think it would be much more convincing to me that there is any merit to
this model if you could show me, for example, how you interact with it in
its non-object form.
It's a question of the mental model, but to my memory even Matz's mental
model does not correspond to yours - i remember seeing a presentation
where he explicitly said that methods were not objects, I can find it
soon hopefully and link it here.
Nonetheless, the book "The Ruby Programming Language" which was
co-written
by Matz has this to say on the matter:
"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."
Hi, John. I suspect that Matz' mental model views methods like this because
he is implementing MRI. For him, this is a necessary model. Aside from
object_id, I can't think of any situation outside of the C code where this
would ever be a useful way of thinking. I would expect that most of the tim=
e
it will just make it more difficult for you to reason about your code,
because your mental model is more complicated due to having have one more
exception for where Ruby behaves unexpectedly that you have to reason
through.
Right after Matz' quote you gave, he says "Blocks, like methods, are not
objects that Ruby can manipulate." But on this topic, I am very much with
Yehuda Katz who says
"In a number of places, it is possible to imbue Ruby semantics with mental
models that reflect the actual Ruby implementation, or the fact that it=92s
possible to imagine that a Ruby object only springs into existence when it
is asked for.
However, these mental models require that Ruby programmers add non-objects
to the semantics of Ruby, and requiring contortions to explain away Ruby=92=
s
own efforts to hide these internals from the higher-level constructs of the
language. For instance, while Ruby internally wraps and unwraps Procs when
passing them to methods, it makes sure that the Proc object attached to a
block is always the same, in an effort to hide the internal details from
programmers.
As a result, explaining Ruby=92s semantics in terms of these internals
requires contortions and new constructs that are not natively part of Ruby=
=92s
object model, and those explanations should be avoided."(
http://yehudakatz.com/2010/02/25/rubys-implementation-does-not-define-its-s=
emantics/
)
That is exactly what I feel is happening here.