Feature #8546

super errors in UnboundMethods

Added by Jim Gay 10 months ago. Updated 10 months ago.

[ruby-core:<unknown>]
Status:Open
Priority:Normal
Assignee:-
Category:-
Target version:-

Description

=begin
(({UnboundMethod}))s are unable to call (({super}))

module M
def hello
puts "hello from M"
end
end

class O
def hello
puts "hello"
end
end

o = O.new
o.hello #=> "hello"
M.instance_method(:hello).bind(o).call #=> "hello from M"

module M
def hello
super
end
end

M.instance_method(:hello).bind(o).call #=> TypeError: self has wrong type to call super in this context: O (expected M)}))

Given that the non-super method works, I would expect super to work.
=end

History

#1 Updated by Nobuyoshi Nakada 10 months ago

  • Tracker changed from Bug to Feature
  • Description updated (diff)

Seems interesting.

#2 Updated by Charles Nutter 10 months ago

I don't see how it would know the order in which to do the super logic. What do you expect to happen?

First off, if the "supering" M was actually included into O, there would still be nothing to super to since its method would be above O's. So I assume you don't want the Method-based "super" to error the same way.

If you would expect the "supering" hello to call O's hello, I'd like to see some justification. That would emulate behavior as if M had been prepended on to O. As it stands, M and O have no hierarchical relationship at all.

I don't think there's other possibilities. What do you want it to do?

#3 Updated by Boris Stitnicky 10 months ago

Holy canolli, since which version is it possible to bind methods to incompatible object types in the first place?

Fuck me running, from 2.0.0. And you keep such an important change for yourself? Do you realize what did I go through trying to cheat 1.9.3 into binding methods to incompatible objects? Lame attempts such as redefining #kind_of?. And in 2.0.0 you say, uh oh, it wasn't a good idea to keep it confined to the source object progeny, we're allowing it now for everyone, sorry for the inconvenience? And nobody mentions this in the lectures about 2.0.0?

#4 Updated by Jim Gay 10 months ago

=begin
headius (Charles Nutter) wrote:

I don't see how it would know the order in which to do the super logic. What do you expect to happen?

First off, if the "supering" M was actually included into O, there would still be nothing to super to since its method would be above O's. So I assume you don't want the Method-based "super" to error the same way.

If you would expect the "supering" hello to call O's hello, I'd like to see some justification. That would emulate behavior as if M had been prepended on to O. As it stands, M and O have no hierarchical relationship at all.

I don't think there's other possibilities. What do you want it to do?

My expectation is that it would call whatever (({hello})) is first available on the singleton_class of (({o})) which in this case is that defined on (({O})).
In other words, my current understanding of how this works is that binding the method is at the most immediate level (the equivalent of prepending a module).

module M
def hello
"hello from M"
end
end

module P
def hello
"prepended #{super}"
end
end

module B
def hello
"binded #{super}"
end
end

class O
include M
prepend P
def hello
super
end
end

o = O.new
puts o.hello #=> "prepended hello from M"
puts B.instance_method(:hello).bind(o).call #=> self has wrong type to call super in this context: O (expected B) (TypeError)

With the new ability to bind methods to arbitrary objects, I was expecting the last line to return the string (({"binded prepended hello from M"}))

=end

Also available in: Atom PDF