Minor Change Proposal for Classes 'Object' and 'Method'

Vincent F. schrieb:

I vote for the last one too !

Vince

An additional method “Kernel#origin(name)” will be helpful, if the
method is
defined as a singleton method for an object, it is difficult to get the
object_id of the anonymous class, where the method ist defined (I hope
this
sentense is somehow understndable).

The object_id is necessary in comparisons with the result of the call to
the
method of class “Method”, that returns the associated class.

Here is some code as an example for the problem (if I didn’t make some
conceptional errors):

class Otto
end
p Otto # => Otto
puts “%x” % Otto.object_id # => 1574ecc
otto = Otto.new
puts “%x” % otto.object_id # => 1574d96
class <<otto
p self # =>
#<Class:#Otto:0x2ae9b2c>
puts “%x” % self.object_id # => 1574d78
def hi
puts “‘Hi!’ from ‘otto’”
end
end
p otto.class # => Otto
puts “%x” % otto.class.object_id # => 1574ecc
p otto.class.superclass # => Object
puts “%x” % otto.class.superclass.object_id # => 15386b6
myottohi = otto.method(:hi)
myottohi[] # => ‘Hi!’ from ‘otto’
p myottohi # => #<Method:
#Otto:0x2ae9b2c.hi>

Wolfgang Nádasi-Donner

Wolfgang Nádasi-Donner wrote:

“Method#origin” returns the object_id of the class where the method belongs too.

Definitely not. See my other post; #origin (or #owner, or whatever)
must return the actual object it refers to, not some indirect method of
referring to that object. You can call #object_id (and any other
method) on the Class instance it returns, if you like.

On 19.01.2007 19:33, Yukihiro M. wrote:

Wolfgang’s proposal can be divided into three methods.

#receiver that returns the bound object of the method object.
#name that returns the name of the method object.
and a method that returns the class which holds the method.

Does anybody have good name candidate for the last one? I have
already implemented the first two methods in the local copy of the
repository.

I opt for “defining_class”, because this precisely states what it
returns. Some might find it a bit much of typing but I think we have
much worse cases in Ruby (attr_accessor for example, which is much more
often used). If someone can come up with an equally clear name which is
shorter, that’s fine with me.

Kind regards

robert

On Sun, 21 Jan 2007, Phrogz wrote:

If we’re going verbose, I prefer #owning_class. Striving for terseness,
however, I prefer #owner. To me, that’s pretty clear.

Uh oh, I think we’re headed to ‘eigner’ :slight_smile:

David

Robert K. wrote:

I opt for “defining_class”, because this precisely states what it
returns. Some might find it a bit much of typing but I think we have
much worse cases in Ruby (attr_accessor for example, which is much more
often used). If someone can come up with an equally clear name which is
shorter, that’s fine with me.

I have two objections to this:

  1. The fact that there are some methods which are a pain to type does
    not mean that we should feel OK about making all methods a pain to
    type. Certainly, verbose naming matters less of the method would be
    infrequently used (as this one would). But we should continually strive
    for a balance between clarity and terseness (and I see that you
    implicitly agree with that, given your last sentence).

  2. If a method is rebound to a new object, what is desired (I think) is
    the current ‘parent’ class of the method, not the one where it was
    defined. If derivatives of the word ‘defined’ are in the method name,
    this (edge) case will be confusing.

If we’re going verbose, I prefer #owning_class. Striving for terseness,
however, I prefer #owner. To me, that’s pretty clear.

Phrogz schrieb:

Wolfgang Nádasi-Donner wrote:

“Method#origin” returns the object_id of the class where the method belongs too.

Definitely not. See my other post; #origin (or #owner, or whatever)
must return the actual object it refers to, not some indirect method of
referring to that object. You can call #object_id (and any other
method) on the Class instance it returns, if you like.

I’m sorry - it came from tom much writing “Method” versus “method” and
“class
Class” and so on in a foreign language…

It’s clear to me that the return values are always objects. This is what
I need,
because I want to compare objects, and, in case of the method name,
symbols.

Wolfgang Nádasi-Donner

[email protected] wrote:

On Sun, 21 Jan 2007, Phrogz wrote:

If we’re going verbose, I prefer #owning_class. Striving for terseness,
however, I prefer #owner. To me, that’s pretty clear.

Uh oh, I think we’re headed to ‘eigner’ :slight_smile:

LOL :slight_smile:
Who could possibly get that confused with anything else? Perfect!
Ship it.

Phrogz schrieb:

p o1 == Foo
#=> true
p o2 == o3
#=> true

The owner of an instance method should be the class on which it is
defined, right? Thus, the owner of a ‘singleton method’
(eigenmethod(?)) would be the (anonymous/singleton/eigen) class. That
would make it easy to get the object_id of that class for the such a
method.

This is what I need.

A question - I wrote a similar proposal for “UnboundMethod”. Is it
possible to
use the same method names (e.g. “owner” and “name”) there?

Wolfgang Nádasi-Donner

On 20.01.2007 18:54, Phrogz wrote:

repository.
infrequently used (as this one would). But we should continually strive
for a balance between clarity and terseness (and I see that you
implicitly agree with that, given your last sentence).

Exactly.

  1. If a method is rebound to a new object, what is desired (I think) is
    the current ‘parent’ class of the method, not the one where it was
    defined. If derivatives of the word ‘defined’ are in the method name,
    this (edge) case will be confusing.

I am not sure I understand what you mean by “parent class”. If you
refer to the class of the instance the method is bound to then that
would be available via meth.receiver.class. When rebinding a method to
another receiver then the defining class does not change, does it? Did
I miss something?

If we’re going verbose, I prefer #owning_class. Striving for terseness,
however, I prefer #owner. To me, that’s pretty clear.

In my ears “owner” sounds more like the instance (“receiver”).
“owning_class” seems clearer although I still prefer “defining_class” as
it seems a bit clearer to me. YMMV though…

Kind regards

robert

On Jan 20, 2007, at 1:38 PM, [email protected] wrote:

I’m not quite understanding the idea of meth.receiver, though. How
does that fit in with the idea of the receiver being whatever object a
given message is sent to (which could, in most cases, be any of many
objects)?

We are talking about the information encapsulated in an instance
of Method, which currently isn’t accessible via introspection (unless
you want to get creative and parse the output of the inspect string).

a = [1,2]
m1 = a.method(‘first’)

m1.receiver # a, i.e. [1, 2]
m1.name # :first
m1.origin # Array

um1 = um1.unbind
um1.receiver # NameError, no such method
um.name # :first
um.origin # Array

m2 = um.bind( [3,4] )
m2.receiver # [3,4]
m2.name # :first
m2.origin # Array

owning_class and defining_class have also been suggest instead of
origin.

I would suggest that owning_module and defining_module would be
more accurate though since classes are modules but modules are not
classes.

Gary W.

Hi –

On Sun, 21 Jan 2007, Robert K. wrote:

not mean that we should feel OK about making all methods a pain to
this (edge) case will be confusing.

I am not sure I understand what you mean by “parent class”. If you refer to
the class of the instance the method is bound to then that would be available
via meth.receiver.class. When rebinding a method to another receiver then
the defining class does not change, does it? Did I miss something?

I think you’re right, because objects don’t have methods, only classes
and modules do.

I’m not quite understanding the idea of meth.receiver, though. How
does that fit in with the idea of the receiver being whatever object a
given message is sent to (which could, in most cases, be any of many
objects)?

David

Hi –

On Sun, 21 Jan 2007, [email protected] wrote:

a = [1,2]
m1 = a.method(‘first’)

m1.receiver # a, i.e. [1, 2]

I guess I find that a bit anomalous because it’s calling a the
“receiver” of a message it may or may not ever have received. I’m not
sure what a better term is, though.

David

[email protected] schrieb:

I’m not quite understanding the idea of meth.receiver, though. How
does that fit in with the idea of the receiver being whatever object a
given message is sent to (which could, in most cases, be any of many
objects)?

“Method#bind” creates an object which contains a fixed object an a fixed
method.
For example “methobj = x.method(:inspect)”. You call it later by
“methobj[]”
or “methobj.call”. So it makes sense to ask “What ist the object the
Method
object ist bound to”, “What is the method the Method object is bound
to”, and
“to which class does the bound method belong to”.

Wolfgang Nádasi-Donner

Hi –

On Sun, 21 Jan 2007, Wolfgang Nádasi-Donner wrote:

the Method object ist bound to", “What is the method the Method object is
bound to”, and “to which class does the bound method belong to”.

Right, but I don’t see that relationship as the same as what we
usually call “receiver”, which is part of the dynamic process of an
object actually receiving a certain message.

David

On Jan 20, 2007, at 2:28 PM, [email protected] wrote:

Right, but I don’t see that relationship as the same as what we
usually call “receiver”, which is part of the dynamic process of an
object actually receiving a certain message.

Yes, but there are two different messages being sent to two different
receivers. It is similar to a proxy pattern. The proxied object
is still a receiver of a message (from the proxy object).

m = -1.method(‘abs’)
m.call

m is the receiver of ‘call’
‘call’ is the name of the method sent to m

-1 is the receiver of ‘abs’
‘abs’ is the name of the method sent to -1

m.name # ‘abs’
m.receiver # -1
m.origin # Fixnum

Perhaps bound_name and bound_receiver makes the relationship clearer?
I would still prefer the shorter names as it doesn’t seem anomalous to
me or at least no more anomalous than any other ‘proxy’ pattern.

Gary W.

[email protected] wrote:

“Method#bind” creates an object which contains a fixed object an a
fixed method. For example “methobj = x.method(:inspect)”. You call it
later by “methobj[]” or “methobj.call”. So it makes sense to ask “What
ist the object the Method object ist bound to”, “What is the method
the Method object is bound to”, and “to which class does the bound
method belong to”.

Right, but I don’t see that relationship as the same as what we
usually call “receiver”, which is part of the dynamic process of an
object actually receiving a certain message.

What about ‘target’, then ? It shows that it is not necessary the
receiver, but that it has been considered as a potential one.

Vince

Hi –

On Sun, 21 Jan 2007, [email protected] wrote:

m = -1.method(‘abs’)
m.origin # Fixnum

Perhaps bound_name and bound_receiver makes the relationship clearer? I would
still prefer the shorter names as it doesn’t seem anomalous to
me or at least no more anomalous than any other ‘proxy’ pattern.

My problem with using “receiver” this way is that it’s detached from
the process of receiving a message. It’s really the object that
would be, or will be, or could be the receiver.

I just foresee lots of need to clarify what one means when one says
“the receiver”. I do think that something indicating “bindee”,
essentially, would make more sense, since what’s being reported is
really the fact that the method is bound to this object – which can
vary independently of the question of whether the object ever actually
receives the message.

David

[email protected] schrieb:

I’ll add that, though it’s a subtle point, I don’t think that objects
receive methods. They receive messages, and act on the basis of those
messages (execute a like-named method or method_missing, or raise an
exception).

This means, that the object bound into a Method object should be named
something
like “caller”. The message receiving and searching for an appropriate
method ist
done by the object during the processing of the “method” message. The
method
found then will be bound to the message object, and later exactly this
method
will be called by the object when using the message object.

Wolfgang Nádasi-Donner

Hi –

On Sun, 21 Jan 2007, [email protected] wrote:

My problem with using “receiver” this way is that it’s detached from
the process of receiving a message. It’s really the object that
would be, or will be, or could be the receiver.

I just foresee lots of need to clarify what one means when one says
“the receiver”. I do think that something indicating “bindee”,
essentially, would make more sense, since what’s being reported is
really the fact that the method is bound to this object – which can
vary independently of the question of whether the object ever actually
receives the message.

I’ll add that, though it’s a subtle point, I don’t think that objects
receive methods. They receive messages, and act on the basis of those
messages (execute a like-named method or method_missing, or raise an
exception).

So I would be reluctant to have any method claim that it was returning
the receiver of a method object.

David

On Jan 20, 2007, at 4:59 PM, [email protected] wrote:

My problem with using “receiver” this way is that it’s detached from
the process of receiving a message. It’s really the object that
would be, or will be, or could be the receiver.

and also:

I’ll add that, though it’s a subtle point, I don’t think that objects
receive methods. They receive messages, and act on the basis of those
messages (execute a like-named method or method_missing, or raise an
exception).

I don’t recall any suggestion that objects receive ‘methods’.
I’ve tried to use the standard ‘messages are sent to objects’
terminology.

I’m not sure why you view the object bound to a Method instance as
somewhat conditional. The only way that that object would not be
the receiver (i.e. the object identified as self when the bound method
body executes) is if Method#call itself was never executed.

At the point that a Method instance is created, the lookup process
that maps a message to a method definition has already been triggered.
Later on, when Method#call gets executed, there is no need for the
method
lookup process to run again. The message is ‘sent’ to the object at
the time Kernel#method is executed and not at the time that Method#call
is executed. It is only the actual execution of the method body that
remains to be completed at some point in the future. It seems a lot
more
definite to me than your ‘would/will/could’ description although I
certainly agree that the final step might never be taken, but that is
also true of things like different branches of an if/else or case
statement.

class A
def foo; 'class A; end
end

a = A.new
m1 = a.method ‘foo’

def a.foo
‘singleton method’
end

m2 = a.method ‘foo’

m1.call # ‘class A’
m2.call # ‘singleton method’

One interesting thing that I noticed is that you can’t capture
a potential use of ‘method_missing’ with Kernel#method:

class A
def method_missing(sym)
‘gotcha’
end
end

m1 = A.new.method ‘foo’ # NameError
A.new.foo # gotcha

It seems like Kernel#method should bind the method_missing
implementation to an instance of Method.

I certainly agree with you that the situation calls for some careful
thought with respect to the naming and terminology. It is easy to
get lost in the multiple layers of context that are inherent in things
like Method and UnboundMethod.

Gary W.