On Fri, Nov 12, 2010 at 04:29:28PM +0900, Josh C. wrote:
Here’s a thought experiment for you:
Why should you be able to do foo(3) ? That would require completely changing
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 if
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)
Why should you be able to do puts(3), if you think we should not be able
to do foo(3)?
You should be able to do foo(3) because you seem to think that the
method
and the object are the same thing. In order to get the object to which
you can send messages, though, you need to do something like I did: get
it out of the “method” method as a return value. What the faiure of
foo(3) to work shows is that when you have a method object you no
longer have a method that can be invoked by sending its name as a
message
to an object. Instead, you have to send a message to it. This
demonstrates that when you interact with foo, you’re no longer
interacting with the method itself.
You’re confusing the method object with the method itself, again. The
reason you should be able to do foo(3) is that, if the method is the
object, you should be able to treat the object like a method. Since you
cannot just call the method object the same way you would call the
object, the method object and the method are obviously not the same
thing.
I’ll try again:
~> irb
irb(main):001:0> puts(3) # treat puts like a method
3
=> nil
irb(main):002:0> puts.call(3) # treat puts like an object
NoMethodError: undefined method `call' for nil:NilClass
from (irb):2
from :0
irb(main):003:0> foo = Kernel.method('puts')
=> #<Method: Kernel.puts>
irb(main):004:0> foo(3) # treat foo like a method
NoMethodError: undefined method `foo' for main:Object
from (irb):4
from :0
irb(main):005:0> foo.call(3) # treat foo like an object
3
=> nil
Is it clear what’s happening hear?
token type treated like status
puts(3) method method success
puts.call(3) method object failure
foo(3) object method failure
foo.call(3) object object success
I don’t know how it can get any clearer than that.
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.
As you can see, this has absolutely nothing to do with what my example
code demonstrated.
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.
See above.
Outside of methods, I wish everything was an object. Alas, bare
keywords
like “if” and “while” are not objects in Ruby. I have no strong feeling
one way or the other at this point about whether methods should or
should
not be objects – but, just like bare keywords, the way they actually
“behave” makes it clear to the discerning observer that they are not
in
fact objects.
Maybe I have a slight advantage because I have spent so much time in my
life on things like truth tables and deductive philosophy. I don’t know
why I saw this so quickly and you insist that it is not true. It is,
though. Sorry.
Just in case another perspective might help, I’ll try one more way of
saying the same thing:
Objects respond to methods. Methods return objects. Objects do not
“return” anything except their own identifiers, and methods do not
respond to messages.