From: Yehuda Katz Date: 2009-01-19T14:16:29+09:00 Subject: [ruby-core:21426] Re: Proposal: Module#copy_method --000e0cd248fa67dc840460cf0bb9 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit I can show that this is not the case in MRI because my very crude hack (which just copies the method) doesn't break super semantics. -- Yehuda On Sun, Jan 18, 2009 at 10:04 PM, Tomas Matousek < Tomas.Matousek@microsoft.com> wrote: > I believe that methods (and blocks defined as methods via method_defined) > are somehow closed over the module that declares them so that "super" can > find the right module/class whose parent's method to call. At least they are > in IronRuby J > > > > A simple copy of a method without changing binding to its declaring module > therefore causes super to fail (or changes its semantics). I think this is > the case even for module_function (I might have an example somewhere that > demonstrates it, will send it tomorrow if I find it). module_function > "copies" the method from declaring module to its singleton class, which is > indeed not derived from the declaring module, breaking super in some > constructed cases. > > > > Tomas > > > > *From:* Yehuda Katz [mailto:wycats@gmail.com] > *Sent:* Sunday, January 18, 2009 3:14 PM > *To:* ruby-core@ruby-lang.org > *Subject:* [ruby-core:21423] Re: Proposal: Module#copy_method > > > > Just FYI, the define_method version fails if your method requires the use > of super. Observe: > > class Zoo1 > def bar > p "In superclass" > 1 > end > end > > class Zoo2 < Zoo1 > def bar > p "in Zoo2mod #{self}" > super + 1 > end > > mod = Module.new do > define_method(:bar, Zoo2.instance_method(:bar)) > end > include mod > > def bar > p "In bar" > super + 1 > end > end > > p Zoo2.new.bar > > The above produces SystemStackError: stack level too deep, infinite-looping > in the original bar implementation on Zoo2. Also, it doesn't work on 1.9. > > -- Yehuda > > On Sun, Jan 18, 2009 at 2:32 PM, Charles Oliver Nutter < > charles.nutter@sun.com> wrote: > > Yehuda Katz wrote: > > I'd like it to be possible to copy methods from one module to another. The > rationale is that this feature would make it possible to modify existing > methods without being forced to resort to aliasing. Here's an implementation > that works on 1.8 and 1.9: > > > > Here's a pure-ruby version that works on an unmodified JRuby: > > require 'jruby' > > class Module > def copy_method(mod, sym) > # get JRuby DynamicMethod object from RubyMethod > org.jruby.RubyMethod.field_reader :method > ruby_method = mod.instance_method(sym) > real_method = JRuby.reference(ruby_method).method > > # native methods may have memory/object layout needs > raise "can't copy native method" if real_method.native? > > # Add it directly to the JRuby RubyModule self > real_modcls = JRuby.reference(self) > real_modcls.add_method(sym.to_s, real_method) > end > end > > - Charlie > > > > > -- > Yehuda Katz > Developer | Engine Yard > (ph) 718.877.1325 > -- Yehuda Katz Developer | Engine Yard (ph) 718.877.1325 --000e0cd248fa67dc840460cf0bb9 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I can show that this is not the case in MRI because my very crude hack (whi= ch just copies the method) doesn't break super semantics.

-- Yehuda

On Sun, Jan 18, 2009 at 1= 0:04 PM, Tomas Matousek <Tomas.Matousek@microsoft.com> wrote:

I believe that methods (a= nd blocks defined as methods via method_defined) are somehow closed over the module that declares them so th= at "super" can find the right module/class whose parent's method to call. At least they are in IronRuby J

 

A simple copy of a method= without changing binding to its declaring module therefore causes super to fail (or changes its semantics). I think t= his is the case even for module_function (I might have an example somewhere tha= t demonstrates it, will send it tomorrow if I find it). module_function "copies" the method from declaring module to its singleton class, which is indeed no= t derived from the declaring module, breaking super in some constructed cases.=

 

Tomas

 

From: Yehuda Katz [mailto:wycats@gmail.= com]
Sent: Sunday, January 18, 2009 3:14 PM
To: rub= y-core@ruby-lang.org
Subject: [ruby-core:21423] Re: Proposal: Module#copy_method

 

Just FYI, the define_method version fails if your method requires the use of super. Observe:

class Zoo1
  def bar
    p "In superclass"
    1
  end
end

class Zoo2 < Zoo1
  def bar
    p "in Zoo2mod #{self}"
    super + 1
  end

  mod =3D Module.new do
    define_method(:bar, Zoo2.instance_method(:bar))
  end
  include mod
 
  def bar
    p "In bar"
    super + 1
  end
end

p Zoo2.new.bar

The above produces SystemStackError: stack level too deep, infinite-looping= in the original bar implementation on Zoo2. Also, it doesn't work on 1.9.<= br>
-- Yehuda

On Sun, Jan 18, 2009 at 2:32 PM, Charles Oliver Nutter <charles.nutter@sun.com&g= t; wrote:

Yehuda Katz wrote:

I'd like it to be possible to copy methods from one module to another. The rationale is that this feature would make it possible to mo= dify existing methods without being forced to resort to aliasing. Here's an implementation that works on 1.8 and 1.9:

 

Here's a pure-ruby version that works on an unmodified JRuby:

require 'jruby'

class Module
 def copy_method(mod, sym)
   # get JRuby DynamicMethod object from RubyMethod
   org.jruby.RubyMethod.field_reader :method
   ruby_method =3D mod.instance_method(sym)
   real_method =3D JRuby.reference(ruby_method).method

   # native methods may have memory/object layout needs
   raise "can't copy native method" if real_method.= native?

   # Add it directly to the JRuby RubyModule self
   real_modcls =3D JRuby.reference(self)
   real_modcls.add_method(sym.to_s, real_method)
 end
end

- Charlie




--
Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325




--
Yehuda Katz
Develope= r | Engine Yard
(ph) 718.877.1325
--000e0cd248fa67dc840460cf0bb9--