Wish list item: Method#to_proc


#1

would this be useful/theoretically possible?
UnboundMethod#to_proc
Thanks!
-=R


#2

On Nov 22, 6:22 pm, Roger P. removed_email_address@domain.invalid wrote:

would this be useful/theoretically possible?
UnboundMethod#to_proc
Thanks!
-=R

Posted viahttp://www.ruby-forum.com/.

I put together an implementation here:
http://github.com/nakajima/rebound/tree/master/lib%2Frebound.rb#L11-13.
Not great, since it relies on Ruby2Ruby, but it worked for what I
needed, which was just to see if I could do it.


#3

On Nov 22, 2008, at 4:22 PM, Roger P. wrote:

would this be useful/theoretically possible?
UnboundMethod#to_proc
Thanks!
-=R

cfp:~ > cat a.rb
class UnboundMethod
def to_proc this = self
bind(self).to_proc
end
end

module M
def m
42
end
end

include M

p M.instance_method(:m)

p M.instance_method(:m).to_proc(self).call

cfp:~ > ruby a.rb
#<UnboundMethod: M#m>
42

the issues is, without binding, what is ‘self’ ??? once bound,
to_proc exists.

a @ http://codeforpeople.com/


#4

On Nov 22, 8:52 pm, “ara.t.howard” removed_email_address@domain.invalid wrote:

 bind(self).to_proc

a @http://codeforpeople.com/

we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama

The main issue with this approach is that instances of UnboundMethod
can only be bound to objects of the same class on which the method was
originally defined. That’s why I used Ruby2Ruby.


#5

On Sun, Nov 23, 2008 at 2:52 AM, ara.t.howard
removed_email_address@domain.invalidwrote:

I guess you meant
bind( this ).to_proc

p M.instance_method(:m).to_proc(self).call

but I guess OP rather wanted
M.i_m(:m).to_proc.call( self )

which on a quick thought seems impossible to have :frowning:

the issues is, without binding, what is ‘self’ ??? once bound, to_proc
exists.

It could be provided at call time, see example above. I kinda like the
idea.

Cheers
Robert


Ne baisse jamais la tête, tu ne verrais plus les étoiles.

Robert D. :wink:


#6

On Nov 23, 2008, at 3:46 AM, Robert D. wrote:

but I guess OP rather wanted
M.i_m(:m).to_proc.call( self )

which on a quick thought seems impossible to have :frowning:

na, just have to perform the late binding in the caller’s stead

cfp:~ > cat a.rb
class UnboundMethod
def to_proc
lambda do |this, *a|
bind(this).to_proc.call(*a)
end
end
end

class Object
def m
42
end
end

p Object.instance_method(:m)
p Object.instance_method(:m).to_proc.call(self)

cfp:~ > ruby a.rb
#<UnboundMethod: Object#m>
42
cfp:~ >

other permutations, such as

cfp:~ > cat a.rb
class UnboundMethod
def to_proc
lambda{|*a| bind(this=self).to_proc.call(*a)}
end
end

class Object
def m() 42 end
end

p Object.instance_method(:m)
p Object.instance_method(:m).to_proc.call

cfp:~ > ruby a.rb
#<UnboundMethod: Object#m>
42

which perform automatic late binding of self are also possible/
preferrable

of course there is the separate issue of what objects an unbound
method can be attached to - but i think an orthogonal solution to
that, plus something simple like the above, can handle most of the
cases. also, ruby19 provides #owner in UnboundMethod, which is useful
for this case i think.

cheers.

a @ http://codeforpeople.com/


#7

cfp:~ > ruby a.rb
#<UnboundMethod: M#m>
42

the issues is, without binding, what is ‘self’ ??? once bound,
to_proc exists.

Cool, though I’ll admit I don’t understand exactly everything that goes
on in there :slight_smile:

My real goal is to be able to share methods from one class to another.

I guess one could “share” methods from class to class [if the method
originated from a module] by searching ancestor modules for a method and
then ‘cherry picking’ it from the ancestor and including it [?]
-=R

http://eigenclass.org/hiki.rb?cmd=view&p=Rename+and+reject+methods+from+included+modules&key=eiffel


#8

Ara Howard wrote:

On Nov 23, 2008, at 3:46 AM, Robert D. wrote:

but I guess OP rather wanted
M.i_m(:m).to_proc.call( self )

which on a quick thought seems impossible to have :frowning:

na, just have to perform the late binding in the caller’s stead
cfp:~ > ruby a.rb
#<UnboundMethod: Object#m>
42

Wow that is dang cool.
Next challenge:
getting a method to transfer “easily” from one class to another [not
directly related classes]. I guess you could do it if the method
originated from a module–is that the only way?

Ex:

module AddToString
def yoyo
‘within string func’
end

end

class String
include AddToString
end

class Object

attempt to find and ‘borrow’ a method from another class

in 1.8, method_name should be a string, in 1.9, not sure

def borrow_and_run_method(from_this, method_name_desired)
module_where_found = nil
for ancestor in from_this.ancestors do
module_where_found ||= ancestor if ancestor.class == Module &&
ancestor.instance_methods.include?(method_name_desired)
end
raise unless module_where_found
m = Module.new
m.module_eval { include module_where_found}
m.instance_methods.each{|method_name| m.module_eval{
undef_method(method_name) unless method_name == method_name_desired } }
# todo: double check we’re not overwriting anything…
self.extend m
self.send method_name_desired
end
end

class NoYoYo; end

print NoYoYo.new.borrow_and_run_method(String, ‘yoyo’) # prints ‘within
string func’