Project

General

Profile

Bug #16106

UnboundMethod owner points to base class

Added by sbellware (Scott Bellware) 6 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
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 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.

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

unbound_method_owner_sketch.rb (176 Bytes) unbound_method_owner_sketch.rb sbellware (Scott Bellware), 08/15/2019 08:17 PM

Updated by alanwu (Alan Wu) 6 months ago

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.

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:

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

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

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.

Also available in: Atom PDF