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

On Jan 22, 2007, at 1:55 PM, Christian N. wrote:

While we are at it, can we please have UnboundMethod#to_proc?
It would greatly help to implement callbacks from class methods.

This doesn’t make sense. Without an object bound to the method
‘self’ will be undefined and so it is nonsensical to try to execute
the associated code. You must bind an object before you’ve got
something usable as a block argument (via the implicit to_proc
conversion).

Do you have some sample code that illustrates your scenario?

Gary W.

Hi,

In message “Re: Minor Change Proposal for Classes ‘Object’ and ‘Method’”
on Mon, 22 Jan 2007 20:30:38 +0900, [email protected] writes:

|I’ve always found it very helpful (for myself and others) to keep the
|whole sequence very visible (message sending, method lookup, method
|execution), and I think that using “receiver” as an attribute of a
|method object does a short-circuit in the terminology that makes it
|harder to explain and understand.

Hmm, OK, what terminology do you use for “this” (or self) in languages
without message passing model (e.g. C++ or Java)? That should be the
appropriate term for it. I use “receiver” for them too, since I have
strong Smalltalk influence.

          matz.

[email protected] wrote:

On Jan 22, 2007, at 1:55 PM, Christian N. wrote:

While we are at it, can we please have UnboundMethod#to_proc?
It would greatly help to implement callbacks from class methods.

This doesn’t make sense. Without an object bound to the method
‘self’ will be undefined and so it is nonsensical to try to execute
the associated code.

Only if the method relies on the ‘self’. For example:

class Foo
def self.square( x )
x*x
end
end

could be reasonably translated to a lambda of:

square = lambda{ |x| x*x }

(I personally don’t have a use case, but its certainly possible in some
scenarios.)

On Jan 22, 2007, at 3:20 PM, Phrogz wrote:

square = lambda{ |x| x*x }
But ‘self’ is still defined within that block even if it isn’t
‘used’. It is a pretty fundamental concept in Ruby that ‘self’ is
always defined. I realize that in the
functional world a lambda only uses its arguments for input, but in
the Ruby world
there is always an implicit receiver hanging around.

Gary W.

Hi,

In message “Re: Minor Change Proposal for Classes ‘Object’ and ‘Method’”
on Tue, 23 Jan 2007 09:14:28 +0900, [email protected] writes:

|I don’t know, in terms of the other languages. I don’t think it’s
|exactly analogous, though. It’s really a bound object, so
|bound_object would probably be the most straightforward.

The term ‘bound_object’ is not suitable for the Method object model in
my brain. I want to retrieve the object corresponding to self in that
method. Among your suggestions, “target” is better than bound_object.
But I still fond of ‘receiver’.

|I’ve also started thinking about the idea of a MethodData class… but
|it’s pretty unformulated.

Hmm, I am looking forward.

          matz.

On Tue, 23 Jan 2007, Yukihiro M. wrote:

my brain. I want to retrieve the object corresponding to self in that
method. Among your suggestions, “target” is better than bound_object.
But I still fond of ‘receiver’.

‘receiver’ makes perfect sense to me. so does ‘this’.

regards.

-a

Hi –

On Mon, 22 Jan 2007, Yukihiro M. wrote:

Hmm, OK, what terminology do you use for “this” (or self) in languages
without message passing model (e.g. C++ or Java)? That should be the
appropriate term for it. I use “receiver” for them too, since I have
strong Smalltalk influence.

I don’t know, in terms of the other languages. I don’t think it’s
exactly analogous, though. It’s really a bound object, so
bound_object would probably be the most straightforward.

I’ve also started thinking about the idea of a MethodData class… but
it’s pretty unformulated.

David

Hi –

On Tue, 23 Jan 2007, [email protected] wrote:

The term ‘bound_object’ is not suitable for the Method object model in
my brain. I want to retrieve the object corresponding to self in that
method. Among your suggestions, “target” is better than bound_object.
But I still fond of ‘receiver’.

‘receiver’ makes perfect sense to me. so does ‘this’.

I don’t think “this” works for, ummm, this. How would you infer that
the “this” here:

m = obj.method(:x)
m.this

refers to obj? I can’t think of an explanation that doesn’t twist and
turn around some bends.

David

[email protected] schrieb:

md = str.method_data(:split) => MatchData object

I Think its a typo - you mean “=> MethodData object” !?

Wolfgang Nádasi-Donner

Hi –

On Tue, 23 Jan 2007, Yukihiro M. wrote:

|I’ve also started thinking about the idea of a MethodData class… but
|it’s pretty unformulated.

Hmm, I am looking forward.

I can give you the very basic idea (and that will save me some further
trouble if you don’t like it :slight_smile:

str = “abc”
md = str.method_data(:split) => MatchData object

md.method => Method object
md.receiver => str
md.method_name => “split”

etc. – something like that.

David

Hi –

On Tue, 23 Jan 2007, Wolfgang Nádasi-Donner wrote:

[email protected] schrieb:

md = str.method_data(:split) => MatchData object

I Think its a typo - you mean “=> MethodData object” !?

Yes – thank you – force of habit! :slight_smile:

David

On Tue, 23 Jan 2007 [email protected] wrote:

trouble if you don’t like it :slight_smile:

str = “abc”
md = str.method_data(:split) => MatchData object

MatchData ??

md.method => Method object
md.receiver => str
md.method_name => “split”

why would the properties of an object be contained outside of the method
object? wouldn’t it be more intuitive to do

m = ‘pols’.method ‘split’

p m.name #=> ‘split’
p m.receiver #=> ‘pols’

it just seems more economic to hang this info off of the method object
itself

??

-a

Hi –

On Tue, 23 Jan 2007, [email protected] wrote:

I can give you the very basic idea (and that will save me some further
trouble if you don’t like it :slight_smile:

str = “abc”
md = str.method_data(:split) => MatchData object

MatchData ??

Typo :slight_smile:

p m.name #=> ‘split’
p m.receiver #=> ‘pols’

Is that subliminal advertising? :slight_smile:

it just seems more economic to hang this info off of the method object itself

We’re back to square one – see my various explanations of why I find
the term “receiver” inexact and confusing for this particular purpose.

David

On Jan 22, 2007, at 8:04 PM, [email protected] wrote

str = “abc”
md = str.method_data(:split) => MatchData object

md.method => Method object
md.receiver => str
md.method_name => “split”

I don’t understand why you are adding another level of indirection.
Take a look at the C code for the Method class. A Method object
already contains pointers to lots of internal information. I think
the original suggestion by Wolfgang really just amounted to exposing
that internal information with suitable names.

Throughout this conversation I kept getting the nagging feeling that
my mental model of the situation was in some important way different
from your mental model of the situation and so we were coming to
different
conclusions. I can’t put my finger on exactly what the difference is
but this suggestion re: MethodData just emphasizes that feeling for
me. We are thinking about this differently–I’m just not sure I
can pin it down to exactly where our thinking diverges.

Gary W.

Hi –

On Tue, 23 Jan 2007, [email protected] wrote:

str = “abc”
md = str.method_data(:split) => MatchData object

md.method => Method object
md.receiver => str
md.method_name => “split”

I don’t understand why you are adding another level of indirection.

Just trying to accomodate the “receiver” label in a context where it
seems less confusing. I’m not sold on the MethodData thing by any
means.

me. We are thinking about this differently–I’m just not sure I
can pin it down to exactly where our thinking diverges.

I think it’s that I see this:

a.x

and this:

m = a.method(:x)
m.call

as two different ways to achieve the goal of executing x with a as
self. In the first, a receives the message “x”. In the second – as
I see it – a does not receive the message “x”; it’s a different path,
a non-message-receiving path, to the same goal.

Therefore, I find the use of “receiver” to describe a in the second
case to be counterproductive, because instead of exactly pinning down
the role that a is playing in that scenario, it tries to characterize
the scenario in terms of the first scenario. I would prefer to find a
term that pinpoints exactly what the object a is in relation to the
method object – not what it will be if the method is called (also
debateable anyway), not what it would have been if we’d done a.x
instead, but what it is.

And saying that a is the “receiver” of the Method object is, I think,
ambiguous (it sounds like a is receiving the Method object) and
incomplete (it doesn’t express, except by a kind of indirect
suggestion, what the relation is between the objects a and m).

The MethodData idea was an attempt to go sort of in the other
direction by abstracting both the Method object and its “bindee”, to
put them on an equal footing. I don’t necessarily endorse it, but
that was my thinking.

David

Hi,

In message “Re: Minor Change Proposal for Classes ‘Object’ and ‘Method’”
on Tue, 23 Jan 2007 20:54:51 +0900, [email protected] writes:

|I think it’s that I see this:
|
| a.x
|
|and this:
|
| m = a.method(:x)
| m.call
|
|as two different ways to achieve the goal of executing x with a as
|self. In the first, a receives the message “x”. In the second – as
|I see it – a does not receive the message “x”; it’s a different path,
|a non-message-receiving path, to the same goal.

Perhaps the message was sent to the object a for both cases. In the
former case, the message was interpreted as a command. In the latter
case, the message was a method selector.

          matz.

Hi –

On Tue, 23 Jan 2007, Yukihiro M. wrote:

|
case, the message was a method selector.
That’s a much more general idea of “receiver” than I’m used to. I
guess we could say that objects (or methods?) are “receivers” of their
arguments, so that here:

3 + 2

3 receives the message 2. I don’t like it, though; I prefer the more
specialized meaning (3 receives the message “+” with the argument 2).

David

Robert D. schrieb:

On 1/23/07, [email protected] [email protected] wrote:

‘receiver’ makes perfect sense to me. so does ‘this’.

it does not make sense to me, it is only a potential receiver at the time
being, the receiver in a Bound Method object is just not a meaningful term.
In order to receive a message a message must be sent.

To me, the main point of this discussion so far has been whether we
should call an object a receiver if it only plays the role of a
receiver but hasn’t acted as a receiver yet. David et al. think this
would be misleading, others (me included) don’t think so. We could go on
and on and I don’t think we’ll come to an agreement.

But is it really true, that after

m = a.method(:x)

the object “a” hasn’t acted as a receiver yet? Look at this code:

class C
def x
“x of #{self}”
end
end

a = C.new
m = a.method(:x)

The method C#x hasn’t been executed yet. Let’s do it in two ways:

puts a.x # => x of #<C:0x2ae912c>
puts m.call # => x of #<C:0x2ae912c>

Now we change the implementation of the method:

class C
remove_method(:x)
def x
“new x of #{self.inspect}”
end
end

puts a.x # => new x of #<C:0x2ae912c>
puts m.call # => x of #<C:0x2ae912c>

The BoundMethod object “m” still uses the old definition. Even after
removing the method…

class C
remove_method(:x)
end

puts a.x rescue puts $! # => undefined method `x’ for #<C:0x2ae912c>
puts m.call # => x of #<C:0x2ae912c>

…we are still able to execute the old implementation. So, if I look at
this example, I don’t think that

m.call

is really sending a message. It just executes the implementation it has
remembered in the context of the original object.

What happens when an object receives a message?

  1. Search a method for the message in the object’s classes/modules.
  2. Execute this method in the context of the object.

If the steps 1) and 2) are separated as in…

m = a.method(:x)
m.call

…I would even say that the receiving part has occurred in step 1),
where the object decides how it wants to react upon the message. In step
2), the object’s role is to execute a given piece of code in its
context.

So, I would say that after

m = a.method(:x)

the object a has at least partly acted as a receiver.

David, could you live with that? :slight_smile:

Regards,
Pit

On 1/23/07, [email protected] [email protected] wrote:

|bound_object would probably be the most straightforward.

The term ‘bound_object’ is not suitable for the Method object model in
my brain. I want to retrieve the object corresponding to self in that
method. Among your suggestions, “target” is better than bound_object.
But I still fond of ‘receiver’.

‘receiver’ makes perfect sense to me. so does ‘this’.

it does not make sense to me, it is only a potential receiver at the
time
being, the receiver in a Bound Method object is just not a meaningful
term.
In order to receive a message a message must be sent.
I have followed David’s crusade :wink: very carefully and it makes lots of
sense
to me to distinguish between what is and what might be.

Now I suspect there are just different conceptions at work, as you are
all
very clever guys (so am I but I hide it on the list).

Maybe this is a critical question:
Do we all agree that a receiver is an entity receiving a message and
nothing
else?

Maybe not.

Cheers
Robert

regards.

On Wed, 24 Jan 2007, Pit C. wrote:

 "new x of #{self.inspect}"

remove_method(:x)
is really sending a message. It just executes the implementation it has
m.call

David, could you live with that? :slight_smile:

Regards,
Pit

very good points. frankly, i find the ‘potentiality’ arguments silly
since
they’re analogous to saying the we shouldn’t use ‘self’ here

class C
def m() self end
end

since, at the time of writing the function, no ‘self’ yet exists. to be
accurte we should probably use

class C
def m() furture_self end
end

but, of course, we don’t.

the point is that, unless code executes as you write it, we are
always
deferring the framing context to the time of execution and chosing terms
that
make sense in that potential context. we use ‘server’ and ‘client’ even
if no
packets will be sent. ‘producer’ and ‘consumer’ and meaningful event
when no
events transpire. ‘source’ and ‘sink’ are perfect logical titles to
relay
meaning as are ‘receiver’ and ‘message’. the eventuality or
potentiality
have, imho, little to do with the use of these terms to define primary
relationships between objects.

regards.

-a