--f+W+jCU1fRNres8c
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Nov 12, 2010 at 04:29:28PM +0900, Josh Cheek wrote:
> On Thu, Nov 11, 2010 at 9:05 PM, Chad Perrin <code / apotheon.net> wrote:
>=20
> > On Thu, Nov 11, 2010 at 04:51:46PM +0900, Josh Cheek wrote:
> >
> > 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 actual=
ly
> > 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:
> >
> >    > foo =3D 1.method('+')
> >    > foo(3)
> >    4
> >    >
> >
> > Fire up irb and try it, now.  It doesn't work.
> >
> > Instead, if you want to use it, you need to do this:
> >
> >    > foo =3D 1.method('+')
> >    > foo.call(3)
> >    4
> >    >
> >
> > That's because a "method object" is not a method; it is a proc that wra=
ps
> > the method and its scope context.
> >
>=20
> Why should you be able to do foo(3) ? That would require completely chang=
ing
> 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:
   =20
    ~> irb
    irb(main):001:0> puts(3)              # treat puts like a method
    3
    =3D> nil
    irb(main):002:0> puts.call(3)         # treat puts like an object
   =20
    NoMethodError: undefined method `call' for nil:NilClass
            from (irb):2
            from :0
    irb(main):003:0> foo =3D Kernel.method('puts')
    =3D> #<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
    =3D> 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.

>=20
> 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.


>=20
> 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.

--=20
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

--f+W+jCU1fRNres8c
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iEYEARECAAYFAkzeFCcACgkQ9mn/Pj01uKUP/ACfa3soZ+oizL/iWUw54xkByhYL
VwoAoMnIMRksCyY6mKzuvSFwuW4SuIyp
=sWfe
-----END PGP SIGNATURE-----

--f+W+jCU1fRNres8c--