Top-posting my own message for a quick correction: class B < A in all =
examples listed.
Michael Edgar
adgar / carboni.ca
http://carboni.ca/

On Jun 7, 2011, at 4:19 PM, Michael Edgar wrote:

> Howdy,
>=20
> I've recently been investigating one of the 1.9 regressions that still =
hasn't been corrected yet, as far as I can tell: implicit super failing =
in methods defined via define_method.
>=20
> The following code works in Ruby 1.8, but not Ruby 1.9:
>=20
> class A
>  def foo(x)
>    p x
>  end
> end
> class B
>  define_method(:foo) do |y|
>    super
>  end
> end
> B.new.foo(2)
>=20
> This is a result of the current bytecode compilation strategy for =
implicit-argument passing for super: when in a method,
> find the method's top-level ISeq (where its arguments can be found), =
insert the appropriate bytecode instructions
> (such as getlocal, etc.) to form the arguments to the super method, =
and run invokesuper.
>=20
> A straightforward attempt to implement such a strategy for a method =
defined with define_method fails for a
> simple reason: one must determine which block's arguments should be =
passed. The following examples make it
> clear why this is difficult:
>=20
> class B
>  define_method(:foo) do |y|
>    y.each do |z|
>      # do I pass z, or y? The answer is y, but how do we know this at =
compilation time?
>      super
>    end
>  end
>=20
>  p =3D proc do |y|
>    proc do |z|
>      puts y
>      # super doesn't even make sense here until we say what method =
it's in, which we
>      # don't currently know at compile time. And even then, is "y" the =
argument to pass? or "z"?
>      super
>    end
>  end
>  define_method(:foo, &p.call(10))
> end
>=20
> That said, this is not an unsolvable problem: it works fine in Ruby =
1.8, JRuby successfully implements
> this capability with bytecode compilation, and while I haven't tried =
it, I expect Rubinius to be okay too.
>=20
> What does seem clear, however, is that the current approach (which =
works fine for methods) does not
> work outside of a method context, and will not. I would like to see =
this addressed in Ruby 1.9.3: it is
> a breaking regression, it does affect real code (my gems have suffered =
from this - RubyLexer, at the
> version I currently target, expects this to work), and it should be =
fixable.
>=20
> At present, this case is detected and raised up on at =
vm_insnhelper.c:1407. It appears that what is
> necessary is to, at that location, perform the necessary introspection =
by following the chain to the
> method definition and examine its parameters, re-performing the =
argument construction that compilation
> would otherwise do. I'm looking into writing a patch that does this, =
but I figured it'd be smart to reach out to
> fellow developers to see if there's something I'm missing - a tough =
reason why this hasn't been done yet,
> current technical limitations, etc. It seems it should be slow, but =
possible.
>=20
> Any thoughts?
>=20
> Michael Edgar
> adgar / carboni.ca
> http://carboni.ca/
>=20
>=20