Submitted by flgr (Mon Feb 14 21:02:06 UTC 2005)
I can not think of an actual sample of what Method#target could be used for right now, but I think it would not hurt to add it either. It's the one that could be removed from this RCR most easily.
The effort to implement this ought to be fairly low as the structs already contain the information anyway. (UnboundMethod#inspect uses it.)
#origin would return the Class or Module where the (Unbound)Method was originally defined. #name would return the original method name as either a String or Symbol. (I prefer Symbol) #target would return the bind target -- the Object the Method is bound to.
It's not so easy with method.origin -- it can be done in case the origin was not an anonymous Module or Class, but it requires a bit more Regexp work and using the module_name.split("::").inject(Object) { |mod, item| mod.const_get(item) } trick.
Method#target can not be implemented at all in pure Ruby as far as I know.
In the proposal I mentioned possibly renaming #name to #original_name -- this is because the #name might already be reused for another method at the time the call is made or not be used at all. See this code sample for when this would happen:
class Foo def x() 1 end end old_x = Foo.instance_method(:x) class Foo remove_method :x # old_x.name still returns :x, but old_x.origin.instance_method(old_x.name) raises an Exception def x() 2 end # old_x.name still returns :x, but old_x.origin.instance_method(old_x.name).bind(obj).call != old_x.bind(obj).call end
I don't think that the behavior is much of a problem when pointed out in the documentation, but I thought pointing it out would be a good idea.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
The Object#__id__ and Object#__send__ methods are named that way because of the enourmously dense namespace they inhabit. For instance, an object representing an XML element might want to define an #id method, and an object representing a network socket might want to define #send. I see no point in using the name Method#__name__, since we don't expect people to subclass Method and define a #name method of their own. It would make about as much sense as Module#__define_method__, Proc#__call__, or even String#__split__.
Could someone explain these better. Primarily what is #target?
#target simply returns the object the method is bound to. 5.method(:+).target would return 5.
Yes, so if we: a = Klass.new b = a.method: name b.target => would return the object that 'a' points to. b.origin => would return Klass.
++ On this one! I logged into RCR to suggest the exact same thing in fact :-p.
I've implemented these methods in Nodewrap. Here's the relevant C implementation. Method#target corresponds to method_receiver, Method#name corresponds to either method_id or method_oid (depending on whether you want the current or original name), and Method#origin corresponds to method_origin_class:
-- Paul Brannan