Forum: Ruby Minor Change Proposal for Classes 'Object' and 'Method'

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Wolfgang N. (Guest)
on 2007-01-19 18:16
(Received via mailing list)
Minor Change Proposal for Classes 'Object' and 'Method'
_______________________________________________________


I would like to make a small change suggestion on the class 'Method' by
which
the method 'Object#method' is also affected.

Background:
___________

When creating a 'Method' object, it is not possible to receive the
object
identification of the object which uses the 'Object#method' method (see
'Example
for Workaround' for details) by using some Method of class 'Method'.

It is useful for some applications to analyse later on which to which
objects a
method is bound in an object of class 'Method'. In addition, it is
simply
missing from my viewpoint, because it is an essential information
(attribute) of
an object of class 'Method'.

A minor wish is an additional method for class 'Method', which returns
the
contents of 'Method#to_s' as an Array containing two elements, the
class-name
and the method-name without the textual border of 'Method#to_s'. It is
easier
and less expensive to return this existing information by a method of
class
'Method', than to use a regular expression later on to extract the
information.

The method names used by here are only suggestions, since I needed names
for the
example. Regarding definite names I have no emotions.

___________


 >>>>> Example for Workaround >>>>>
class Object
   alias :_org_method :method
   def method(name)
     method_object = self._org_method(name)
     method_object.instance_id = self.object_id
     method_object
   end
end

class Method
   attr_accessor :instance_id
   def method_name
     md = self.to_s.match(/Method:\s*([^#]+)#([^>]+)>/)
     return md[1], md[2]
   end
end

# Now an example

class Hugo
   def hi
     puts "An instance of Hugo says 'Hi!'"
   end
end

my_hugo = Hugo.new
puts my_hugo.object_id     # => 22497820 (for example)
myhi = my_hugo.method(:hi)
myhi[]                     # => An instance of Hugo says 'Hi!'
puts myhi.instance_id      # => 22497820 (for example)
p myhi.method_name         # => ["Hugo", "hi"]
 >>>>>     End of Example     >>>>>

___________


Please inform me, if this is not the right place for a change proposal.

Wolfgang Nádasi-Donner (WoNáDo)
Yukihiro M. (Guest)
on 2007-01-19 18:53
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Sat, 20 Jan 2007 01:15:05 +0900, Wolfgang Nádasi-Donner
<removed_email_address@domain.invalid> writes:

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

|my_hugo = Hugo.new
|puts my_hugo.object_id     # => 22497820 (for example)
|myhi = my_hugo.method(:hi)
|myhi[]                     # => An instance of Hugo says 'Hi!'
|puts myhi.instance_id      # => 22497820 (for example)
|p myhi.method_name         # => ["Hugo", "hi"]

Why object_id?  Isn't it more useful to return the receiver itself,
e.g.

  myhi.receiver  # => #<Hugo:0xb7d5ff40>

?

And why should method_name return combination of class name and method
name?  I think the method_name should return the method name only
("hi" for this case).  It may be useful to implement separate method
to get a class that holds the method.

              matz.
Wolfgang N. (Guest)
on 2007-01-19 19:46
(Received via mailing list)
Yukihiro M. schrieb:
> to get a class that holds the method.
I agree, because I'm only interested in the information at all. If you
find a
better format or better way to present it, its fine.
One question is open for 'myhi.receiver  # => #<Hugo:0xb7d5ff40>'.

First, the  format requires a pattern matching on the result, if the
object-id
ist needed only. May be two seperate methods are better, as you
suggested for
'method_name'.

In additon, a format for the seperate method, that returns information
about the
class that holds the method, may be complicated for singleton methods.
An
example is '#<Method: #<Hugo:0x2ae6e54>.private_hi>'.

Wolfgang Nádasi-Donner (WoNáDo)
Kalman N. (Guest)
on 2007-01-19 20:06
(Received via mailing list)
Yukihiro M.:
> And why should method_name return combination of class name and method
> name?  I think the method_name should return the method name only
> ("hi" for this case).

I agree here.  Furthermore I think that #name would be a better name, in
analogy to Module#name.

Kalman
Kalman N. (Guest)
on 2007-01-19 20:08
(Received via mailing list)
Wolfgang Nádasi-Donner:
> One question is open for 'myhi.receiver  # => #<Hugo:0xb7d5ff40>'.
>
> First, the  format requires a pattern matching on the result, if the object-id
> ist needed only.

May you elaborate? Where do you need pattern matching here?

Kalman
Yukihiro M. (Guest)
on 2007-01-19 20:12
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Sat, 20 Jan 2007 03:05:10 +0900, Kalman N. 
<removed_email_address@domain.invalid>
writes:

|Wolfgang Nádasi-Donner:
|> One question is open for 'myhi.receiver  # => #<Hugo:0xb7d5ff40>'.
|>
|> First, the  format requires a pattern matching on the result, if the object-id
|> ist needed only.
|
|May you elaborate? Where do you need pattern matching here?

I think he supposed receiver returns above string, but it doesn't.  It
returns the object reference.  If you need object-id, you can get it
from

  myhi.receiver.object_id

              matz.
Wolfgang N. (Guest)
on 2007-01-19 20:15
(Received via mailing list)
Kalman N. schrieb:
> Wolfgang Nádasi-Donner:
>> One question is open for 'myhi.receiver  # => #<Hugo:0xb7d5ff40>'.
> May you elaborate? Where do you need pattern matching here?

myhi.receiver.match(/:([^>]+)>/)[1] # => "0xb7d5ff40"

and I need 'eval' to compare the textual presentation of the object-id
with the
object-id I receive from "Object#object_id" (or I have to convert this
result to
an textual hex-presentation)
Wolfgang N. (Guest)
on 2007-01-19 20:16
(Received via mailing list)
Yukihiro M. schrieb:
> I think he supposed receiver returns above string, but it doesn't.  It
> returns the object reference.  If you need object-id, you can get it
> from
>
>   myhi.receiver.object_id

I see - I thought it is a string, sorry.

Wolfgang Nádasi-Donner
Yukihiro M. (Guest)
on 2007-01-19 20:34
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Sat, 20 Jan 2007 01:52:36 +0900, Yukihiro M.
<removed_email_address@domain.invalid> writes:

|Why object_id?  Isn't it more useful to return the receiver itself,
|e.g.
|
|  myhi.receiver  # => #<Hugo:0xb7d5ff40>
|
|?

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.

              matz.
Brad E. (Guest)
on 2007-01-19 20:42
(Received via mailing list)
On Jan 19, 2007, at 12:33 PM, Yukihiro M. wrote:

> |  myhi.receiver  # => #<Hugo:0xb7d5ff40>
> |
> |?
>
> 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'm kind of partial to #owner myself.
unknown (Guest)
on 2007-01-19 21:46
(Received via mailing list)
On Sat, 20 Jan 2007, 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.

object.where? "method_name"  # returns nil if not defined

object.definer "method_name"  # same as above


another idea:

   m = object.def "method_name"  # an uber-bound method object

   p m.name      #=> "method_name"
   m.call *a, &b #=> same as object.method_name *a, &b

kind regards.

-a
Daniel B. (Guest)
on 2007-01-19 21:55
(Received via mailing list)
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.

Method#parent

Dan
Vincent F. (Guest)
on 2007-01-19 22:03
(Received via mailing list)
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.

 What about origin ? Or even of ?

  method.of => MyClass

  Cheers,

  Vince
unknown (Guest)
on 2007-01-19 22:37
(Received via mailing list)
On Jan 19, 2007, at 1:33 PM, 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.

Method#receiver
Method#name
Method#origin           # module/class with definition of method

Kernel#origin(name)     # module/class where named method is found
      # via standard method lookup process on the
                         # receiver.
                         # nil if no matching method found

Kernel#origin!(name)    # same as origin but reports location of
                         # any matching method_missing implementation
                         # nil if no method_missing applies

Not sure about origin vs. origin! names but it seems reasonable
to be interested in whether method_missing is triggered or not.

I've often thought it might be nice to have a 'magic' reference
similar to 'self' that referenced a method object matching the
current receiver and method:

def factorial(n)
   return 1 if n.zero?
   myself[n-1] * n
end

So in that example, 'myself' would be an instance of Method bound
to the top-level object and the method Object#factorial.

Combined with the other proposed methods you get:

  myself.name  # => 'factorial'
  myself.receiver  # => main
  myself.origin  # => Object

Not sure about the 'myself' name, but I like the idea.

Gary W.
Vincent F. (Guest)
on 2007-01-20 02:13
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> Method#receiver
> Method#name
> Method#origin           # module/class with definition of method
>
> Kernel#origin(name)     # module/class where named method is found
>             # via standard method lookup process on the
>                         # receiver.
>                         # nil if no matching method found

  I vote for the last one too !

  Vince
Wolfgang N. (Guest)
on 2007-01-20 12:41
(Received via mailing list)
Vincent F. schrieb:
>   I vote for the last one too !
>
>   Vince

I don't think it works well with "Kernel#origin(name)" because the
lookup result
may change when changing the class definitions. The method, which
returns the
class name, should be directly related to the existing "Method" object.
Example:

 >>>>> Example >>>>>
class Otto
   def hi
     puts "'Hi!' from an Otto instance"
   end
end

class Hugo < Otto
end

o1 = Hugo.new
mymeth1 = o1.method(:hi)

class Hugo < Otto
   def hi
     puts "'Hi!' from a Hugo instance"
   end
end

mymeth2 = o1.method(:hi)

mymeth1[] # => 'Hi!' from an Otto instance
mymeth2[] # => 'Hi!' from a Hugo instance

p mymeth1 # => #<Method: Hugo(Otto)#hi>
p mymeth2 # => #<Method: Hugo#hi>
 >>>>> End of Example >>>>>

Wolfgang Nádasi-Donner
Wolfgang N. (Guest)
on 2007-01-20 17:20
(Received via mailing list)
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
unknown (Guest)
on 2007-01-20 17:56
(Received via mailing list)
On Jan 20, 2007, at 10:20 AM, Wolfgang Nádasi-Donner wrote:

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

I was assuming that Method#origin and Kernel#origin would both
return a reference to the class/module.  In fact, Kernel#origin
is really just  short for method(name).origin and of course
you can just call object_id on the module/class reference as needed.

It appears that you are viewing the (proposed) return value of
Method#origin and Kernel#origin as a string and not as a reference
to the module/class itself as intended by myself and the other
posters.

Gary W.
Wolfgang N. (Guest)
on 2007-01-20 18:45
(Received via mailing list)
removed_email_address@domain.invalid schrieb:
>>>>             # via standard method lookup process on the
>> The object_id is necessary in comparisons with the result of the call
> posters.
Sorry, I am a little bit confused in the moment...

What I like to say is, that in case of

class Otto
   def hi
     puts "Hi"
   end
end
o = Otto.new
my1 = o.method(:hi) # Class Otto, Method hi
class << o
   def hi
     puts "Hihi"
   end
end
my2 = o.method(:hi) # Class -anonymous-, Method hi

"Method#origin" returns the object_id of the class where the method
belongs too.
Thats clear for me. The problem I see is, that for the second
Method-object
"my2" "Method#origin" returns an object_id on an anonymous class.

If later on I want to find out if my Method objects reference a method,
that is
defined in an anonymous class, I will have problems to get the object_id
of this
anonymous class without an additional "Kernel#origin(name)" method, that
returns
the object_id of the anonymous class in case of (e.g) "o.origin(:hi)".
The
result should not be the same before and after "class << o".

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-20 19:06
(Received via mailing list)
On Jan 20, 2007, at 11:45 AM, Wolfgang Nádasi-Donner wrote:
> "Method#origin" returns the object_id of the class where the method
> belongs too. Thats clear for me.

No. the return value isn't the object_id (a Fixnum).  It is a
reference to the class/module itself.  Same idea with Kernel#origin

This is the same pattern as with Kernel#class:

a = Hash.new
a.object_id  # a Fixnum
a.class    # reference to Hash, i.e. the class itself

b = a.class.new  # a newly created instance of Hash

m = Hash.method('invert')  # an instance of Method
m.origin  # a reference to Hash

h = m.origin.new # another instance of Hash is created


Gary W.
Gavin K. (Guest)
on 2007-01-20 19:15
(Received via mailing list)
Wolfgang Nádasi-Donner wrote:
> 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).

Could you explain what you mean by this? I would assume that this would
work:

  class Foo; def bar1; end; end
  f = Foo.new
  def f.bar2; end

  o1 = f.method( :bar1 ).owner
  o2 = f.eigenclass  # class << f; self; end
  o3 = f.method( :bar2 ).owner
  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.
Gavin K. (Guest)
on 2007-01-20 19:20
(Received via mailing list)
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.
Robert K. (Guest)
on 2007-01-20 19:40
(Received via mailing list)
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
Gavin K. (Guest)
on 2007-01-20 19:56
(Received via mailing list)
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.
unknown (Guest)
on 2007-01-20 20:04
(Received via mailing list)
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' :-)


David
Wolfgang N. (Guest)
on 2007-01-20 20:09
(Received via mailing list)
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
Robert K. (Guest)
on 2007-01-20 20:16
(Received via mailing list)
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.

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

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
Gavin K. (Guest)
on 2007-01-20 20:18
(Received via mailing list)
removed_email_address@domain.invalid 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' :-)

LOL :)
Who could possibly get that confused with anything else? Perfect!
Ship it.
Wolfgang N. (Guest)
on 2007-01-20 20:21
(Received via mailing list)
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
unknown (Guest)
on 2007-01-20 20:40
(Received via mailing list)
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
unknown (Guest)
on 2007-01-20 21:17
(Received via mailing list)
On Jan 20, 2007, at 1:38 PM, removed_email_address@domain.invalid 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.
Wolfgang N. (Guest)
on 2007-01-20 21:26
(Received via mailing list)
removed_email_address@domain.invalid 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
unknown (Guest)
on 2007-01-20 21:28
(Received via mailing list)
Hi --

On Sun, 21 Jan 2007, removed_email_address@domain.invalid 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
unknown (Guest)
on 2007-01-20 21:30
(Received via mailing list)
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
Vincent F. (Guest)
on 2007-01-20 21:31
(Received via mailing list)
removed_email_address@domain.invalid 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
unknown (Guest)
on 2007-01-20 22:04
(Received via mailing list)
On Jan 20, 2007, at 2:28 PM, removed_email_address@domain.invalid 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.
unknown (Guest)
on 2007-01-20 22:12
(Received via mailing list)
Hi --

On Sun, 21 Jan 2007, removed_email_address@domain.invalid 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
unknown (Guest)
on 2007-01-20 23:59
(Received via mailing list)
Hi --

On Sun, 21 Jan 2007, removed_email_address@domain.invalid 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
Wolfgang N. (Guest)
on 2007-01-21 00:26
(Received via mailing list)
removed_email_address@domain.invalid 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
unknown (Guest)
on 2007-01-21 05:19
(Received via mailing list)
On Jan 20, 2007, at 4:59 PM, removed_email_address@domain.invalid 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.
Robert K. (Guest)
on 2007-01-21 12:57
(Received via mailing list)
On 20.01.2007 20:30, Vincent F. wrote:
> removed_email_address@domain.invalid 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.
>
>   What about 'target', then ? It shows that it is not necessary the
> receiver, but that it has been considered as a potential one.

Go for it!  "target" sounds perfect to me.

Now, what do we do about the class method? :-)

Kind regards

  robert
unknown (Guest)
on 2007-01-21 13:50
(Received via mailing list)
Hi --

On Sun, 21 Jan 2007, removed_email_address@domain.invalid wrote:

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

I don't view the binding as conditional; I just don't think the word
"receiver" describes the binding.  Also, your second sentence is
exactly my point: there is a perfectly plausible scenario where the
object would *not* be the receiver.

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

I don't think that's right.  Sending a message to an object means (or
always has meant) asking the object to find and execute a method with
a matching name.  What you're doing here is a different operation.

Going back to basics:

   a.x
   a.send(:x)

In these two statements, a is receiving the message x.  That doesn't
happen when you do this:

   a.method(:x)

or this:

   a.respond_to?(:x)

etc.  You're answering questions related to the receipt of x by a, but
a is not receiving x.

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

Right -- and here:

   if false
     a = 3
   end

I would not describe a as equal to 3 :-)

Actually, this:

   a.method(:x).call

is in a sense a way to arrange for a *not* to receive the message x,
but to execute x in a different way.  So "receiver" doesn't even
really become relevant if the method gets called.  a is really a kind
of un-receiver.


David
Wolfgang N. (Guest)
on 2007-01-21 16:46
(Received via mailing list)
removed_email_address@domain.invalid schrieb:
>   a.respond_to?(:x)
I think "a" receives the message "x" only in the first case. The second
one
means '"a" receives the message "send" and the parameter ":x"'. The rest
is
similar with messages "method" and "respond_to?", both with parameter
":x".

It's up to the actions that will be startet to handle the parameter
":x".

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-21 17:30
(Received via mailing list)
Hi --

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

>>
>>   a.respond_to?(:x)
>
> I think "a" receives the message "x" only in the first case. The second one
> means '"a" receives the message "send" and the parameter ":x"'.

Yes, I agree, though I still think it's reasonable to say that, as a
result of the send operation, a receives the message :x.  In any case,
I included it because it demonstrates that there's a "meta" or
two-step way of getting a message to an object, but that a.method(:x)
isn't such a technique.


David
Wolfgang N. (Guest)
on 2007-01-21 18:21
(Received via mailing list)
removed_email_address@domain.invalid schrieb:
> In any case,
> I included it because it demonstrates that there's a "meta" or
> two-step way of getting a message to an object, but that a.method(:x)
> isn't such a technique.

"mo = a.method(:x)" creates a new object "mo" of class "Method", which
contains
the object "a" and a reference (or however to name this) to a method. To
find
the method, ":x" will be interpreted as a message "x" to object "a", but
the
corresponding method will not be executed, but referenced in the new
Method object.

When writing "mo.call" the object "a" will be enforced to use the method
referenced by "mo" without any method lookup. This means, that the
actual state
of object "a" will be used to call a method, which may be overwritten in
the
meantime.

The name "receiver" for a method of class "Method", which returns the
object for
which "method" was called makes some sense, because in the moment
"method" was
called, the referenced method inside the "Method" object would be
executed by
the object when receiving the message named by the parameter for the
"method"
method.

 >>>>> Code >>>>>
class Otto
   attr_accessor :id
   def hi
     puts "'Hi!' from an instance of 'Otto' with id #{self.id}"
   end
   def initialize(id)
     self.id = id
   end
end

otto = Otto.new(42)
myhi = otto.method(:hi)

otto.hi      # => 'Hi!' from an instance of 'Otto' with id 42
myhi.call    # => 'Hi!' from an instance of 'Otto' with id 42

class Otto
   def hi
     puts "'Hihihi!' from an instance of 'Otto' with id #{self.id}"
   end
end

otto.id = 84

otto.hi      # => 'Hihihi!' from an instance of 'Otto' with id 84
myhi.call    # => 'Hi!' from an instance of 'Otto' with id 84

class Otto
   remove_method :hi
end

myhi.call    # => 'Hi!' from an instance of 'Otto' with id 84
otto.hi      # => MethodSuchReihe.rb:33: undefined method `hi' for
              # => #<Otto:0x2ae9af0 @id=84> (NoMethodError)
 >>>>> EOC >>>>>

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-21 19:04
(Received via mailing list)
Hi --

On Mon, 22 Jan 2007, Wolfgang Nádasi-Donner wrote:

> in the new Method object.
I think we're talking past each other.

> When writing "mo.call" the object "a" will be enforced to use the method
> referenced by "mo" without any method lookup. This means, that the actual
> state of object "a" will be used to call a method, which may be overwritten
> in the meantime.
>
> The name "receiver" for a method of class "Method", which returns the object
> for which "method" was called makes some sense, because in the moment
> "method" was called, the referenced method inside the "Method" object would
> be executed by the object when receiving the message named by the parameter
> for the "method" method.

That's all correct, but the word "receiver" doesn't communicate it to
me.  Given this:

   m = a.method(:x)

I do not consider it optimal to describe a as m's "receiver".  It's a
re-definition of the term, and I think it would lead to confusion.

That doesn't mean that there's no relationship between m and a.  It
just means that the word "receiver" isn't the right word to describe
that relationship.  I'd rather see:

   m.target
   m.bound_object

etc. -- something other than m.receiver.


David
Wolfgang N. (Guest)
on 2007-01-21 19:40
(Received via mailing list)
removed_email_address@domain.invalid schrieb:
> That doesn't mean that there's no relationship between m and a.  It
> just means that the word "receiver" isn't the right word to describe
> that relationship.  I'd rather see:
>
>   m.target
>   m.bound_object
>
> etc. -- something other than m.receiver.

I see - I'm not used to use often English since a while, so these
details were
not visible for me.

It is better that native english speakers will define the names.

But now I'm really interested in the names, the methods will have in the
implementation.

Wolfgang Nádasi-Donner
Robert D. (Guest)
on 2007-01-21 20:43
(Received via mailing list)
On 1/21/07, Wolfgang Nádasi-Donner <removed_email_address@domain.invalid> 
wrote:
>
> I see - I'm not used to use often English since a while, so these details
> were
> not visible for me.
>
> It is better that native english speakers will define the names.
>
> But now I'm really interested in the names, the methods will have in the
> implementation.


I do not want to play the wise guy, but what David said took me a very
long
time to understand and yet seems so simple now.
Normally the stupid one having understood can explain much better,
forgive
me for the blunt try:

A method just does not have a receiver, that is completely correct.
A message sent to a receiver may trigger a method which than is called
with
the receiver.
A method bound to an object (and I will not define the name ;) of course
is
a very likely receiver of a message triggering an eventual call of the
bound
method.

Confusing? or did I get it wrong?

Cheers
Robert


Wolfgang Nádasi-Donner
Yukihiro M. (Guest)
on 2007-01-22 02:11
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Mon, 22 Jan 2007 02:03:35 +0900, removed_email_address@domain.invalid 
writes:

|That's all correct, but the word "receiver" doesn't communicate it to
|me.  Given this:
|
|   m = a.method(:x)
|
|I do not consider it optimal to describe a as m's "receiver".  It's a
|re-definition of the term, and I think it would lead to confusion.

"a.method(:x)" looks up a method corresponding message :x, so that we
can invoke the method later.  It is more accurate to call it "target"
or "bound_method", as you pointed.  But I feel like there's a
convention to call the target (or self) of a method as a "receiver" in
OOP context.  Given that context, it's natural to call "a" receiver.

              matz.
unknown (Guest)
on 2007-01-22 02:28
(Received via mailing list)
Hi --

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

> |I do not consider it optimal to describe a as m's "receiver".  It's a
> |re-definition of the term, and I think it would lead to confusion.
>
> "a.method(:x)" looks up a method corresponding message :x, so that we
> can invoke the method later.  It is more accurate to call it "target"
> or "bound_method", as you pointed.  But I feel like there's a
> convention to call the target (or self) of a method as a "receiver" in
> OOP context.  Given that context, it's natural to call "a" receiver.

I disagree; I don't think it's natural in context, because "receiver"
is a dynamic role and the result of a.method(:x) is reflective.
method(:x) is more like a variation on respond_to?(:x).  Neither of
them actually puts the object in the receiver role; they just examine
the current type of the object.

With Method#receiver, We'd end up saying things like, "obj is the
receiver of this method", which sounds like a mistake ("method" for
"message"), and also sounds like obj has actually played the receiver
role.

I don't know -- it just seems that with so many words available, it's
better not to re-use a word that's not a complete fit, even if it's
related to the same problem domain.


David
Yukihiro M. (Guest)
on 2007-01-22 02:58
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Mon, 22 Jan 2007 09:27:28 +0900, removed_email_address@domain.invalid 
writes:

|> "a.method(:x)" looks up a method corresponding message :x, so that we
|> can invoke the method later.  It is more accurate to call it "target"
|> or "bound_method", as you pointed.  But I feel like there's a
|> convention to call the target (or self) of a method as a "receiver" in
|> OOP context.  Given that context, it's natural to call "a" receiver.
|
|I disagree; I don't think it's natural in context, because "receiver"
|is a dynamic role and the result of a.method(:x) is reflective.

I am not sure the difference between dynamic and reflective.

|method(:x) is more like a variation on respond_to?(:x).  Neither of
|them actually puts the object in the receiver role; they just examine
|the current type of the object.

It is a receiver of message that retrieves a method corresponding a
certain message name.  The object is a receiver when the method was
invoked by ordinary message sending.

|With Method#receiver, We'd end up saying things like, "obj is the
|receiver of this method", which sounds like a mistake ("method" for
|"message"), and also sounds like obj has actually played the receiver
|role.

Ah, I already say so often.  The "receiver" is most quick term for me
to describe "self" in a method.

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

represents

  a.x(args)

given that we can invoke the particular method, message "x" passing is
done somewhere in above sequence, and "a" is a receiver of the passing.

              matz.
unknown (Guest)
on 2007-01-22 03:17
(Received via mailing list)
On Jan 21, 2007, at 6:50 AM, removed_email_address@domain.invalid wrote:
>
>   if false
>     a = 3
>   end
>
> I would not describe a as equal to 3 :-)

Sure but I think you've confused the issue a bit by using assignment,
which isn't a method call.  If we consider:

    if rand > 0.5
      a.reverse
    end

Isn't it fair to say that 'a' is the receiver of the 'reverse' message
even though half the time the message will never be sent?

> Actually, this:
>
>   a.method(:x).call
>
> is in a sense a way to arrange for a *not* to receive the message x,
> but to execute x in a different way.  So "receiver" doesn't even
> really become relevant if the method gets called.  a is really a kind
> of un-receiver.

This one, really has me scratching my head.  Certainly there is a method
body that gets invoked by 'a.method(:x).call' and during the
execution of
that method body, self and 'a' will reference the same object.  Isn't it
fair to say then that 'a' (or more accurately the object referenced by
'a') is the receiver of the message that caused the method body to
be invoked? The fact that the lookup of the method body for message
'x' is separated in time from the execution of the method body doesn't
really change the fact that 'a' is the receiver of the message, does it?

I'm using 'method body' to be clear that I'm not talking about an
instance
of Method.

Gary W.
unknown (Guest)
on 2007-01-22 03:24
(Received via mailing list)
Hi --

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

> |
> |I disagree; I don't think it's natural in context, because "receiver"
> |is a dynamic role and the result of a.method(:x) is reflective.
>
> I am not sure the difference between dynamic and reflective.

What I mean is: the object becomes a receiver because it actually
receives a message.  a.method(:x) tells us that a has an "x" method,
but it does not actually involve a set of events where a plays the
role "receiver".

> |method(:x) is more like a variation on respond_to?(:x).  Neither of
> |them actually puts the object in the receiver role; they just examine
> |the current type of the object.
>
> It is a receiver of message that retrieves a method corresponding a
> certain message name.  The object is a receiver when the method was
> invoked by ordinary message sending.

Yes... but this is a different scenario.  I think it's important for
the terminology to reflect that.  It's true that if obj.method(:x)
exists, then obj responds to "x" and can receive "x".  But it's still
separate things.

> |With Method#receiver, We'd end up saying things like, "obj is the
> |receiver of this method", which sounds like a mistake ("method" for
> |"message"), and also sounds like obj has actually played the receiver
> |role.
>
> Ah, I already say so often.  The "receiver" is most quick term for
> me to describe "self" in a method.

But when you do: a.method(:x), there's no self in a#x because a#x has
not been called.

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

(Is that thread-safe? :-)

> represents
>
>  a.x(args)
>
> given that we can invoke the particular method, message "x" passing is
> done somewhere in above sequence, and "a" is a receiver of the passing.

But what does:

   m = a.method(:x)

represent -- *without* making the call to the method?  At that point,
there has been no event (direct or indirect) where a has received "x".
All we've done is create a Method object, based on a's interface.  The
only message-receiving is a receiving "method", but not "x".


David
unknown (Guest)
on 2007-01-22 03:29
(Received via mailing list)
Hi --

On Mon, 22 Jan 2007, removed_email_address@domain.invalid wrote:

>> Right -- and here:
>  if rand > 0.5
>> is in a sense a way to arrange for a *not* to receive the message x,
> 'x' is separated in time from the execution of the method body doesn't
> really change the fact that 'a' is the receiver of the message, does it?

But it's exactly that separation in time that's critical:

   m = a.method(:x)

   # Right here, independently of whether or not m ever gets called,
   # we're starting to talk about m's "receiver", which I
   # think is very confusing terminology.  Objects don't receive
   # methods, this object hasn't even received the message whose
   # name corresponds to this method -- it hasn't even received it
   # indirectly.

   m.call   # This may or may not happen; it's not relevant to the
            # question of whether the relation between m and a is
            # that a is the "receiver" of m.

> I'm using 'method body' to be clear that I'm not talking about an instance
> of Method.

The instance of Method is what's involved though -- that is, whether
it should have a "receiver" method.


David
unknown (Guest)
on 2007-01-22 05:19
(Received via mailing list)
On Jan 21, 2007, at 8:27 PM, removed_email_address@domain.invalid wrote:
>> I'm using 'method body' to be clear that I'm not talking about an
>> instance
>> of Method.
>
> The instance of Method is what's involved though -- that is, whether
> it should have a "receiver" method.

Sure, but I wasn't talking about one or the other but the
relationship between
the two. I couldn't just call them both 'method' because that would
be confusing
so I called one 'method body' and the other 'instance of method'.  I
was trying to
be clear and I'm not aware of any particular standard terminology for
these things
so I picked 'method body'.  Other choices might have been 'method
definition' or,
if you like looking at the internals, a C pointer to a METHOD struct.


Gary W.
unknown (Guest)
on 2007-01-22 05:24
(Received via mailing list)
On Jan 21, 2007, at 8:19 PM, removed_email_address@domain.invalid wrote:
> But what does:
>
>   m = a.method(:x)
>
> represent -- *without* making the call to the method? At that point,
> there has been no event (direct or indirect) where a has received "x".
> All we've done is create a Method object, based on a's interface.  The
> only message-receiving is a receiving "method", but not "x".

In my mind, the Method instance represent that future event.  It is
a model of a Ruby concept (which has no concise name): the final
delivery
of a message to an object.  And at the point that the message is finally
delivered (i.e. the chuck of code is executed) isn't it reasonable to
say
that the object has 'received' the message (:x) and so it is the
'receiver'?
Of course my answer is 'yes' and since I view a Method instance as
modeling that
future event, using 'receiver' as the accessor is not confusing *to me*.

Perhaps the class shouldn't be called Method but instead
MethodInvocation or
BoundMethodInvocation (and UnboundMethodInvocation of course).  Maybe
the
shortened versions omit too much of the context?

Gary W.
Yukihiro M. (Guest)
on 2007-01-22 05:27
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Mon, 22 Jan 2007 10:19:07 +0900, removed_email_address@domain.invalid 
writes:

|>  a.x(args)
|>
|> given that we can invoke the particular method, message "x" passing is
|> done somewhere in above sequence, and "a" is a receiver of the passing.
|
|But what does:
|
|   m = a.method(:x)
|
|represent -- *without* making the call to the method?  At that point,
|there has been no event (direct or indirect) where a has received "x".
|All we've done is create a Method object, based on a's interface.  The
|only message-receiving is a receiving "method", but not "x".

Ordinary message passing

  a.x

does the following steps

  (1) retrieve a class of the object a.
  (2) look-up method table in a class by name x
  (3) if it doesn't exist, looks for super-class table
  (4) invoke a method with self bound to the object a.

whereas

  a.method(:x)

does steps 1 through 3, and creates a method object reserved for the
4th step.  When we can call the object a in the former sequence a
receiver, what is wrong calling receiver too in the latter sequence,
even though target or bound_object is more accurate.  Do you think
possible confusing critical?

              matz.
unknown (Guest)
on 2007-01-22 13:31
(Received via mailing list)
Hi --

On Mon, 22 Jan 2007, removed_email_address@domain.invalid wrote:

>
> In my mind, the Method instance represent that future event.  It is
> a model of a Ruby concept (which has no concise name): the final delivery
> of a message to an object.  And at the point that the message is finally
> delivered (i.e. the chuck of code is executed) isn't it reasonable to say
> that the object has 'received' the message (:x) and so it is the 'receiver'?
> Of course my answer is 'yes' and since I view a Method instance as modeling
> that future event, using 'receiver' as the accessor is not confusing
> *to me*.

I understand what you mean about the future event, but I'm still not
getting why it wouldn't be better to model what's happening *now*.
Why the imperative to skip over that part?  What would be lost if the
object bound to the method were referred to as the object bound to the
method, rather than the receiver of a message it hasn't received?

In general I think it's important to keep the phases -- message
receiving, method lookup, method execution -- conceptually separate.
Not in informal discussion, perhaps, but definitely in available
terminology.  Otherwise one ends up having to back-pedal in order to
explain method_missing, class/module order, etc.

> Perhaps the class shouldn't be called Method but instead MethodInvocation or
> BoundMethodInvocation (and UnboundMethodInvocation of course).  Maybe the
> shortened versions omit too much of the context?

Something does :-)


David
unknown (Guest)
on 2007-01-22 13:52
(Received via mailing list)
Hi --

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

> |But what does:
>  a.x
>  a.method(:x)
>
> does steps 1 through 3, and creates a method object reserved for the
> 4th step.  When we can call the object a in the former sequence a
> receiver, what is wrong calling receiver too in the latter sequence,
> even though target or bound_object is more accurate.  Do you think
> possible confusing critical?

I think the possible confusion can be avoided, so I'd rather avoid it.
If you do this:

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

I can understand saying that a is the receiver of :x (even though it's
an "exploded" path to message-receiving).  But the terminology I don't
like is saying that a is the "receiver" of *m*:

   m.receiver    # a

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.


David
Yukihiro M. (Guest)
on 2007-01-22 14:52
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Mon, 22 Jan 2007 20:30:38 +0900, removed_email_address@domain.invalid 
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.
Christian N. (Guest)
on 2007-01-22 20:56
(Received via mailing list)
Yukihiro M. <removed_email_address@domain.invalid> writes:

> |?
>
> 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.

While we are at it, can we please have UnboundMethod#to_proc?
It would greatly help to implement callbacks from class methods.
unknown (Guest)
on 2007-01-22 22:02
(Received via mailing list)
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.
Gavin K. (Guest)
on 2007-01-22 22:22
(Received via mailing list)
removed_email_address@domain.invalid 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.)
unknown (Guest)
on 2007-01-23 00:20
(Received via mailing list)
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.
unknown (Guest)
on 2007-01-23 02:15
(Received via mailing list)
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
Yukihiro M. (Guest)
on 2007-01-23 02:47
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Tue, 23 Jan 2007 09:14:28 +0900, removed_email_address@domain.invalid 
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.
unknown (Guest)
on 2007-01-23 02:54
(Received via mailing list)
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
unknown (Guest)
on 2007-01-23 03:04
(Received via mailing list)
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 :-)

   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
unknown (Guest)
on 2007-01-23 03:10
(Received via mailing list)
Hi --

On Tue, 23 Jan 2007, removed_email_address@domain.invalid 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
Wolfgang N. (Guest)
on 2007-01-23 03:15
(Received via mailing list)
removed_email_address@domain.invalid schrieb:
>   md = str.method_data(:split)   => MatchData object

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

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-23 03:18
(Received via mailing list)
Hi --

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

> removed_email_address@domain.invalid schrieb:
>>   md = str.method_data(:split)   => MatchData object
>
> I Think its a typo - you mean "=> MethodData object" !?

Yes -- thank you -- force of habit! :-)


David
unknown (Guest)
on 2007-01-23 04:53
(Received via mailing list)
On Tue, 23 Jan 2007 removed_email_address@domain.invalid wrote:

> trouble if you don't like it :-)
>
>  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
unknown (Guest)
on 2007-01-23 06:23
(Received via mailing list)
On Jan 22, 2007, at 8:04 PM, removed_email_address@domain.invalid 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.
unknown (Guest)
on 2007-01-23 13:38
(Received via mailing list)
Hi --

On Tue, 23 Jan 2007, removed_email_address@domain.invalid wrote:

>>
>> I can give you the very basic idea (and that will save me some further
>> trouble if you don't like it :-)
>>
>>  str = "abc"
>>  md = str.method_data(:split)   => MatchData object
>
> MatchData ??

Typo :-)

>
>  p m.name     #=> 'split'
>  p m.receiver #=> 'pols'

Is that subliminal advertising? :-)

> 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
unknown (Guest)
on 2007-01-23 13:56
(Received via mailing list)
Hi --

On Tue, 23 Jan 2007, removed_email_address@domain.invalid 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
Robert D. (Guest)
on 2007-01-23 13:58
(Received via mailing list)
On 1/23/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> 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 ;) 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.
Yukihiro M. (Guest)
on 2007-01-23 14:56
(Received via mailing list)
Hi,

In message "Re: Minor Change Proposal for Classes 'Object' and 'Method'"
    on Tue, 23 Jan 2007 20:54:51 +0900, removed_email_address@domain.invalid 
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.
unknown (Guest)
on 2007-01-23 16:03
(Received via mailing list)
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
Pit C. (Guest)
on 2007-01-23 17:50
(Received via mailing list)
Robert D. schrieb:
> On 1/23/07, removed_email_address@domain.invalid <removed_email_address@domain.invalid> 
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? :-)

Regards,
Pit
unknown (Guest)
on 2007-01-23 18:01
(Received via mailing list)
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? :-)
>
> 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
Robert D. (Guest)
on 2007-01-23 18:25
(Received via mailing list)
On 1/23/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> > don't think we'll come to an agreement.
I completely agree, but I feel that the argument teaches me a lot.

> >    end
> > Now we change the implementation of the method:
> >
> >
> > ...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.


That is very interesting but funnily enough IMHO it makes it even more
counter-intuitive to call a m's receiver.
As a matter of fact I know that I cannot go into the depth of the
implementation that is why I have asked the question:
"Do we agree  that the only thing having a receiver is a message"
Obviously we do not.
But in that case, what can have a receiver? A method? A method-call? A
method object?

OMG we might end up in an endless loop.


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


... by fixing the code, yep that is an excellent argument, but it is not
true in all cases

m= a.method(:x)
m.unbind
m.bind(a.class.new)

so at least the decision you were talking about was not final, the code
stays the same but the receiver changes.
I try hard to figure if one can argument as such in your setup, canyou?
or
are we still miles apart?

In step 2), the
> > object's role is to execute a given piece of code in its context.


or the methods role to execute a given piece of code in a context in
which
the object it is bound to becomes the receiver.

> > Pit
> >


Honestly Ara  I am disappointed by the tone of your post, I do not
recognize
you, this is very  subtle a discussion and the s***y word has just no
place
in it.
I would frankly ignore it by people I know less but....
Now  if I  overreact I apologize, I am not a native speaker.

very good points.  frankly, i find the 'potentiality' arguments silly
since
>      def m() furture_self end
>    end
>
> but, of course, we don't.


That is completely OT we were talking about Runtime "self" is perfectly
defined at execution of the method, while at point (x) receiver is not -
but
is in your setup I start to guess that now.
m = a.method(:x)
------(x)--------
a.call

you can put any code between the two lines as I have mentioned above.

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.


But given a server S and a client C, it would be incorrect to name S C's
server before C has sent a packet to S. We are clearly talking runtime
and
not time of conception.

We are not saying that receiver is bad a name for an object. We think it
is
bad a name for a relationship between Method and the object it is bound
to
at a given state during runtime.
When the method is called the relationship between its bound object and
itself can be described as receiver before it is misleading.

'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
> --
> we can deny everything, except that we have the possibility of being
> better.
> simply reflect on that.
> - the dalai lama
>
>
Robert
unknown (Guest)
on 2007-01-23 18:37
(Received via mailing list)
Hi --

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

> hasn't *acted* as a receiver yet. David et al. think this would be
>    def x
>  puts m.call  # => x of #<C:0x2ae912c>
>  puts a.x     # => new x of #<C:0x2ae912c>
>  puts m.call              # => x of #<C:0x2ae912c>
>
> 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? :-)

If I can send people to you when they ask for an explanation of the
double meaning :-)


David
unknown (Guest)
on 2007-01-23 18:40
(Received via mailing list)
On Wed, 24 Jan 2007, Robert D. wrote:

>
> Honestly Ara  I am disappointed by the tone of your post, I do not recognize
> you, this is very  subtle a discussion and the s***y word has just no place
> in it.  I would frankly ignore it by people I know less but....  Now  if I
> overreact I apologize, I am not a native speaker.
>

hi robert-

sorry to offend - i wasn't even trying to stir the pot!  i chose the 's'
word
precisely because the whole affair doesn't seem worth having strong
feelings
on.  i'll bow out of the discussion then since my feelings on the topic
certainly aren't strong - i just felt like people we're splitting hairs
and
thought i'd point out other accepted terms where people could easily do
the
same, but don't.

as always, i suppose it's better to post working ruby code than rants in
english: they are more precise!  ;-)

kind regards.

-a
Robert D. (Guest)
on 2007-01-23 18:53
(Received via mailing list)
On 1/23/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> > overreact I apologize, I am not a native speaker.
> and
> thought i'd point out other accepted terms where people could easily do
> the
> same, but don't.
>
> as always, i suppose it's better to post working ruby code than rants in
> english: they are more precise!  ;-)
>
> kind regards.


There are few people that could offend me, you can, you did not but I
found
it unpleasant to read no big deal, thx for the explanation.
Yes indeed  that explains it, for me this argument is *very important*
but
that is also a good reason to bail out as taking things so much to heart
does not allow for a clear look.
Besides I have made my points, and there are more qualified people to
decide.

Would be interesting to get insulted in pure ruby code. ;)
Cheers
Robert

-a
Gavin K. (Guest)
on 2007-01-23 19:10
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> On Wed, 24 Jan 2007, Pit C. wrote:
[snip]
> > 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? :-)
>
> If I can send people to you when they ask for an explanation of the
> double meaning :-)

FWIW, it totally makes sense to me for "m.receiver" to return the
object a in the above. Whether it's a Method instance, or a MethodData
instance, we're asking questions about the method itself...which
includes "what will happen when I call this method?". Given that, and
given that I agree with Ara's point about future references, I'm happy
to call the #probable_future_receiver just #receiver. It's the only
receiver that the method knows about at the time of asking, anyhow
(right?).
Luke I. (Guest)
on 2007-01-23 19:19
(Received via mailing list)
On Wed, 24 Jan 2007 02:10:08 +0900
"Phrogz" <removed_email_address@domain.invalid> wrote:

> >
> (right?).
>
>
To me (whom no one knows, or probably cares about), calling it target
would imply that it could be changed... calling it receiver correctly
implies the context of immutability.
unknown (Guest)
on 2007-01-23 19:55
(Received via mailing list)
Hi --

On Wed, 24 Jan 2007, removed_email_address@domain.invalid wrote:

>  class C
>    def m() furture_self end
>  end
>
> but, of course, we don't.

I've come to think that:

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

does not involve a receiving the message "x", in any useful sense of
the term "receiving".  So I don't think it's just a matter of avoiding
"future" in a case where something will happen in the future; rather,
it's a different scenario from a.x.  It's avoiding "receiver" in a
case where the object in question is not the receiver of the message
in question.

But I'm in a tiny minority on every phase and nuance of this, so
that's probably that :-)


David
Trans (Guest)
on 2007-01-23 20:35
(Received via mailing list)
removed_email_address@domain.invalid wrote:

> does not involve a receiving the message "x", in any useful sense of
> the term "receiving".  So I don't think it's just a matter of avoiding
> "future" in a case where something will happen in the future; rather,
> it's a different scenario from a.x.  It's avoiding "receiver" in a
> case where the object in question is not the receiver of the message
> in question.
>
> But I'm in a tiny minority on every phase and nuance of this, so
> that's probably that :-)

I would avoid using the term 'reciever' for wholly different reason --
it has a sense of direction. not a big deal, but directional words can
sometimes have unsuspected consequences in how statements read.

As an alternative I will suggest 'subject' --as in the subject of a
sentence or predicate.

T.
Gavin K. (Guest)
on 2007-01-23 20:42
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> in question.
I love the direction and depth that this discussion has taken and
continues to take. Fascinating tying down of abstract concepts :)

David, if you don't think of it as "receiving" the message, what do you
think of it as doing instead?

In Pit's 2 step (find method associated with a message, execute the
code for that method), the word 'receive' doesn't exist, except for the
implicit "I handed you a message that you're supposed to find the
method for." So let's look at "m.call".

That's invoking the method with the 'self' set to 'a', right? Is it the
"bound_object" for the method?
Christian N. (Guest)
on 2007-01-23 22:01
(Received via mailing list)
"Phrogz" <removed_email_address@domain.invalid> writes:

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

Let me try to remember it... I actually grepped the logs:

Dec 08 14:14:05 <chris2>        i want to use ordinary ruby modules as a
mean to extend a lambda based object system

Anyway, the case was I had a callback that was a module method, and I
wanted an easy way to turn it into a proc.

irb(main):001:0> module M; def foo; "foo!"; end; end
=> nil
irb(main):002:0> M.instance_method(:foo)
=> #<UnboundMethod: M#foo>

I imagine this to be useful for building DSLs, bundling callbacks etc,
too?  At least, allow binding unbound methods to nil without
raising... that would make the not-existing self explicit, too:

irb(main):004:0> M.instance_method(:foo).bind(nil)
TypeError: bind argument must be an instance of M
Robert D. (Guest)
on 2007-01-23 22:50
(Received via mailing list)
On 1/23/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> >    def m() self end
>
> I've come to think that:
>
>    m = a.method(:x)
>    m.call
>
> does not involve a receiving the message "x", in any useful sense of
> the term "receiving".  So I don't think it's just a matter of avoiding
> "future" in a case where something will happen in the future; rather,
> it's a different scenario from a.x.


Sorry Ara I promised to bail out but I am just asking a question, just
too
curious.

David I am losing you here, probably you just look further than me but
as
well on a conceptional view as on an implementation's view (method_call
in
eval.c if I recall correctly) m.call just sends the message :x to the
object
it is bound to.
If you avoid that notion, what else could there be? Method invocation
without message passing would this have benefits on the conceptional
level?
Hmm yes indeed it might close the discussion about receiver but I feel
it
would open a difficulty in describing this kind of invocation. Maybe it
would be worth it.

Far above my horizon but eager to learn.



 It's avoiding "receiver" in a
> case where the object in question is not the receiver of the message
> in question.
>
> But I'm in a tiny minority on every phase and nuance of this, so
> that's probably that :-)


Yes indeed if you prefer to answer offlist I would be very happy too.
OTOH
someone who has gone through the trouble and effort of going through a
paradigm change will always be a minority first, right (c.f. my
signature)

David
>
> --
> Q. What is THE Ruby book for Rails developers?
> A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
>     (See what readers are saying!  http://www.rubypal.com/r4rrevs.pdf)
> Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
> A. Ruby Power and Light, LLC (http://www.rubypal.com)
>
>
Cheers
Robert
unknown (Guest)
on 2007-01-24 00:45
(Received via mailing list)
Warning: The following is pretty long but it has an interesting
surprise ending. At least it surprised me and I even think David will
find it quite satisfying (and maybe even Matz).

On Jan 23, 2007, at 12:54 PM, removed_email_address@domain.invalid wrote:
> in question.
>
> But I'm in a tiny minority on every phase and nuance of this, so
> that's probably that :-)

I have no way of knowing who is in the minority on this issue but I
very much agree with Robert D.'s sentiments:  "... I feel that
the argument teaches me a lot".

The only reason that I keep tugging at this thread is that David
had thrown into doubt my assumption that every method in Ruby
executes within the context of a 'receiving' object which is
syntactically identified by 'self'.  I've generally found David's
thinking on the more dusty corners of Ruby semantics to be very
illuminating so his suggestion that the concept of 'receiver' didn't
apply with respect to instances of Method came out of left field for me.

I wonder if we can brake the logjam a bit by thinking about the
situation in a different way.  Given:

class A
   def x(b,c); self; end
end

obj = A.new

consider the following snippets of code:

obj.x(1,2)                        #  1
obj.foo_then_bar(:x, 1, 2)        #  2
obj.foo(:x).bar(1,2)              #  3

Case 1 is just the normal method invocation.

Case 2 is a way to name the method via an expression but is otherwise
the same as case 1.  The name 'foo_then_bar' hints that this is a two
step process.

Case 3 explicitly breaks up case 2 into two distinct steps.

Lets look at the same code with some different terminology:

obj.x(1,2)                        #  1
obj.resolve_then_apply(:x, 1, 2)  #  2
obj.resolve(:x).apply(1,2)        #  3

I've tried to pick names that suggest appropriate semantics without
dragging in the controversial semantics we've been talking about.
This suggests that:

    f = obj.resolve(:x)

must return an object that encapsulates a reference to obj and also
encapsulates a reference to the definition of A#x found by
'resolving' :x relative to obj. This object must also respond to
'apply' such that

    f.apply(1,2)

causes A#x to be called with the arguments 1 and 2.

Of course I hope everyone who is still reading has figured out that
obj.resolve_then_apply(:x, 1, 2) is just our old friend 'send':

   obj.send(:x, 1, 2)

And within this context we've been happily saying things like:

   The message :x is sent to obj.

   obj is the receiver of the message :x

   When A#m executes, 'self' points to obj.

   When A#m executes, obj is the implicit receiver.

   obj receives message :x, searches for a matching method, and
   then executes the method with arguments 1 and 2.

As long as 'send' is viewed on the outside as a complete process
the send/receive terminology works quite fine. But...

... if we think of the process not as 'send' but instead as
'resolve_then_apply(:x, 1,2)' or 'resolve(:x).apply(1,2)' then
the send/receive metaphor starts to fall apart.

It wasn't until I finally wrote all this out that I really started
to understand what David was getting at.  When I started writing
this post I didn't expect to end up at this point.

I believe David has been suggesting all along that if we hit the
pause button just after the 'resolution' process has finished but
before the 'apply' process has started, then at that moment it can
be said that 'obj' has received :x, i.e. there is no more 'receiving'
to be done, that part of the process is done, finito, fait accompli.
All that is left is the 'apply' process.

Going back to the code:

  f = obj.resolve(:x)  # 1
  f.apply(1,2)         # 2

During step 1, obj receives message :x and resolves the message into
a method definition which is captured and returned within f.

During step 2, the arguments 1 and 2 are applied to obj using the
method definition that was previously resolved.

If we switch the example back to the standard names we get:

  m = obj.method(:x)   # m is an instance of Method
  m.call(1,2)

So to bring this back full circle.  David pointed out that

  m.receiver           # obj

was 'anomolous' because m (an instance of Method) is all about
the 'apply' step of the process and *not* about the 'resolve'
step of the process.  In the 'resolve' step, obj is the
receiver of the message but that step is water under the bridge
once you've constructed an instance of Method.

And here is the real problem: We don't have any accepted terminology
for the role of obj during the 'apply' process.

We never needed any because Method doesn't have an accessor for
that data.  It never needed to be named.  And then Wolfgang posted
his message with the innocuous sounding title of "Minor Change
Proposal for Classes 'Object' and 'Method'."

Matz pointed out that all along it has been quite common to refer
to the object associated with 'self' as the implict or default
receiver.  So why not use Method#receiver?  It made sense to me.

The gotcha is that in:

   def m1(a,b)
     m2
   end

self is the implicit receiver of the message :m2 but we can't
really say anything at all about self with respect to :m1
because the question just isn't meaningful from the
perspective of the execution of m1.  It is only a meaningful
question from the perspective of how m1 came to be executed.

   obj.m1(1,2)      # obj is the receiver

or

   m = obj.method(:m1)  # obj receives and resolves :m1 here

   m.call(1,2)          # the empty argument list is applied
                        # to obj and the resolved method

I know I'm probably splitting hairs at this point but that is
exactly what Kernel#method does and I *think* it is exactly
what David was pointing out.

Here is yet another way to illustrate this hair splitting
that makes it blindingly obvious (to me at least) what
David was getting at:

   a = [1,2]
   b = [3,4]

   fa = a.method(:first)
   uf = fa.unbind
   fb = uf.bind(b)
   fb.call    # 3

Question:
   Where in this example does b receive the message :first?

Answer:
   Nowhere, because b is never the receiver of the message :first.

I'm hoping that David is jumping up and down now saying

  I told you so!

Taking all this into consideration, I think that Vincent F.'s
suggestion of Method#target is a pretty good one.  The object
captured within an instance of Method is the 'target' of the
'apply' process I described above.  It also suggests that when
talking about 'self' within an instance method we might use
terminology such as:

     self is the target of the method and is
     the receiver of any unqualified messages

I also realized that there are circumstances where 'self' is not
the target of any method at all but is still a receiver of
messages:

class X
   attr :foo
end

Within a class block, self is the implicit or default receiver of
messages but is not the 'target' of any particular method.


Gary W.
unknown (Guest)
on 2007-01-24 00:48
(Received via mailing list)
If you haven't read the parent message to this, this won't make any
sense...


When I first wrote out:

   obj.x(1,2)                        #  1
   obj.resolve_then_apply(:x, 1, 2)  #  2
   obj.resolve(:x).apply(1,2)        #  3

I saw this interesting possibility:

   obj.resolve(:x, 1).apply(2)

I don't have a very strong functional programming knowledge but I
believe this is an example of currying.  It suggests that Kernel#method
and Module#instance_method could be be extended to have this
functionality:

   dfirst = Array.instance_method(:delete, 1)
   a = [1,2]
   dfirst.bind(a).call
   a   # [2]

It would be nice if you could stuff this curried method back into
the class under a new name.  The problem is that you can't pass an
UnboundMethod instance to Module#define_method.  UnboundMethod#to_proc
doesn't exist and even if it did, it would be a pretty strange
instance of Proc since it would not be callable.  This concept was
also suggested by Christian N..

Maybe there is some room to play around with the semantics of
methods/blocks/procs?

Gary W.
Pit C. (Guest)
on 2007-01-24 12:21
(Received via mailing list)
Robert D. schrieb:
> (... something like the following ...)

   ma = a.method(:x)
   mb = ma.unbind.bind(b)

Robert, this is a nice counter example to what I've written. In this
case the object "b" surely hasn't received anything. So I guess its role
is really only that of a #bound_object.

Regards,
Pit
unknown (Guest)
on 2007-01-24 21:13
(Received via mailing list)
On Jan 24, 2007, at 5:20 AM, Pit C. wrote:

> Robert D. schrieb:
>> (... something like the following ...)
>
>   ma = a.method(:x)
>   mb = ma.unbind.bind(b)
>
> Robert, this is a nice counter example to what I've written. In
> this case the object "b" surely hasn't received anything. So I
> guess its role is really only that of a #bound_object.

In going back through this thread I realized that I hadn't understood
the
implications of Robert's suggestion at the time.  In my recent long post
about this I 'rediscovered' his example.  So I certainly wasn't the
first
person to point out this situation.

For me personally, I didn't really understand David's uneasiness about
Method#receiver until I realized that the 'send/receive' metaphor only
describes an early *portion* of the entire message dispatch process even
though it is almost always used (inaccurately in my mind) to describe
the entire process.


Gary W.
Wolfgang N. (Guest)
on 2007-01-26 18:20
(Received via mailing list)
I don't know where to put this message into the very large discussion
tree, so I
  will put it here.

There is an argument against naming a method "receiver", which returns
the
object which was bound to a method object.

 >>>>> Example >>>>>

class Otto
   def hi
     puts "'Hi!' from an 'Otto' instance (#{self.inspect})"
   end
end

class Hugo < Otto
   def hi
     puts "'Hi!' from an 'Hugo' instance (#{self.inspect})"
   end
end

o  = Otto.new
h  = Hugo.new
bo = o.method(:hi)
bh = bo.unbind.bind(h)

h.hi    # => 'Hi!' from an 'Hugo' instance (#<Hugo:0x2aea4dc>)
bh.call # => 'Hi!' from an 'Otto' instance (#<Hugo:0x2aea4dc>)
bo.call # => 'Hi!' from an 'Otto' instance (#<Otto:0x2aea478>)

 >>>>> EoE >>>>>

In this example, the "Method" object "bh" contains (I temporary use this
wording
  for this example) the object "h", and the method "Otto#hi", which can
be seen
in the output of "bh.call" - but - if ones sends the message "hi" to the
object
"h" the method "Hugo#hi" will be used (see output for "h.hi").

This means, that for the object "h" contained in "Method" object "bh" a
message
"hi" will not end up in calling "Otto#hi", because it finds "Hugo#hi".

It is misleading to call "h" the "receiver" of a message, that leads to
the
invocation of "Otto#hi", because this cannot be done by any message in
this example.

May be a different name is better to avoid confusion.

Wolfgang Nádasi-Donner
Wolfgang N. (Guest)
on 2007-01-26 18:36
(Received via mailing list)
Sorry, I didn't recognize, that this was already named. More than 90
posts in
this discussion are very much...

Wolfgang Nádasi-Donner
Wolfgang N. (Guest)
on 2007-01-30 12:25
(Received via mailing list)
Hi!

I don't know how you handle "Change Proposals" for Ruby. Implement them
silently
or write somewhere an announcement, so I try to summarize what happens,
as I
understood it.

Please correct me if I'm wrong, because I will report about the results
in the
german Ruby forum.

I include my proposal for class "UnboundMethod" here, because I think it
is
strongly related to this one.

----------------------------

As I understood, the will be some new methods available now or in the
near
future in the repository (or the nightly snapshot). I'm not sure about
the
chosen names, so please correct them.

==============
Class "Method"
==============

Public instance Methods:

receiver
--------
"receiver" returns the bound object of the method object. E.g. for "mo =
o.method(:m)" the expression "mo.receiver" will return "o".

name
----
"name" returns the name of the method object. E.g. for "mo =
o.method(:m)" the
expression "mo.name" will return ":m" (symbol) or "'m'" (string).

owner
-----
"owner" returns the class which holds the method. E.g. for "mo =
o.method(:m)"
the expression "mo.owner" will return "c", if the method ":m", that is
bound to
"mo", is defined in this class. If the class is an anonymous class, it
will be
handled correctly.

=====================
Class "UnboundMethod"
=====================

Public instance Methods:

name
----
"name" returns the name of the method object. E.g. for "mo =
o.method(:m)" the
expression "mo.name" will return ":m" (symbol) or "'m'" (string).

owner
-----
"owner" returns the class which holds the method. E.g. for "mo =
o.method(:m)"
the expression "mo.owner" will return "c", if the method ":m", that is
bound to
"mo", is defined in this class. If the class is an anonymous class, it
will be
handled correctly.

-----------------------

Is it a correct summary. There are so many messages in the discussion,
that I
ended up in comfusion about the chosen names, sorry.

Wolfgang Nádasi-Donner
This topic is locked and can not be replied to.