wish list item: Method#to_proc

A

ara.t.howard

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/
 
R

Roger Pack

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 :)

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
 
P

Pat Nakajima

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/

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

Robert Dober

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 :(
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=
 
A

ara.t.howard

bind( this ).to_proc


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

which on a quick thought seems impossible to have :-(

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/
 
R

Roger Pack

Ara said:
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'
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top