Bug #16106
closed
UnboundMethod owner points to base class
Added by sbellware (Scott Bellware) over 5 years ago.
Updated about 5 years ago.
ruby -v:
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin17]
[ruby-core:94372]
Description
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 SomeBaseClass
rather 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.
Example:
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?
Thanks,
Scott
Files
Yes, this behavior is expected. Changing it would not be backwards compatible.
I think owner in this case means the entity under which the method is originally defined.
Perhaps the documentation can be improved to reflect this.
I guess the documentation could mention that behaviour so that other
rubyists won't be confused, as alanwu pointed out e. g:
https://ruby-doc.org/core/UnboundMethod.html#method-i-owner
(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
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.
- Status changed from Open to Closed
The documentation for owner
states: 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.
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.
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0