UnboundMethod owner points to base class
This may not be a bug. It may be my misinterpretation of the feature.
When using UnboundMethod#owner on a class that was created with
Class.new(SomeBaseClass), the owner is reported as the
SomeBaseClassrather than the new class.
This was a surprising outcome, since I presumed that the owner method would point to the class rather than the class's base class.
class SomeClass def some_method end end C = Class.new(SomeClass) m = C.instance_method(:some_method) pp m.owner # => SomeClass # I would have expected the owner to be C
Is this expected behavior?
Updated by shevegen (Robert A. Heiler) 6 months ago
I guess the documentation could mention that behaviour so that other
rubyists won't be confused, as alanwu pointed out e. g:
(Or the other documentation site; I just happen to find the above
more readily via a quick google search.)
On a side note, perhaps the name is not ideal, since I can see why
sbellware may be surprised - UnboundMethod implies to me a method
not attached to anywhere, so I was a bit surprised to see that it
still has a pointer to the original class from where it was created
from. Although I understand that this may be useful; it just seems
a bit peculiar to me ... perhaps it is a MostlyUnboundMethod. :P
Updated by sbellware (Scott Bellware) 6 months ago
Indeed, that's why I was surprised. I wasn't expecting
owner to be a pointer to a class that I wasn't working with.
To correct the code I was working on, I now pass around both the UnboundMethod instance as well as the class, and ignore the
owner method entirely.
I guess what also throws me, from a usability perspective, is that
owner seems asymmetrical with Method#receiver, where Method#receiver is a pointer to the de facto instance that the method is from. I appreciate that this is largely immaterial due to the difference between objects and classes, but just a bit of background on what was informing my biases at the time.
Ideally, it might have been nice to have a method named
implementer on UnboundMethod that does what
owner does, and have
owner reflect some symmetry with Method#receiver. Just a thought.
Updated by jeremyevans0 (Jeremy Evans) 6 months ago
- Status changed from Open to Closed
The documentation for
Returns the class or module that defines the method.. The example given in the documentation shows
method being called on a Range instance, but having an owner of Enumerable. So I don't think documentation updates are necessary, and this can be closed.
Updated by Eregon (Benoit Daloze) 5 months ago
An interesting bit here is that there is no way to get back the module from which the method was retrieved, even though it's shown in #inspect:
> Range.instance_method :map => #<UnboundMethod: Range(Enumerable)#map>
Maybe we should expose
UnboundMethod#origin? That would be a separate feature request, though.