From: Yehuda Katz Date: 2009-01-19T08:14:23+09:00 Subject: [ruby-core:21423] Re: Proposal: Module#copy_method --000e0cd248fa687e0a0460c9fcc0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 --000e0cd248fa687e0a0460c9fcc0 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Just FYI, the define_method version fails if your method requires the use o= f super. Observe:

class Zoo1
  def bar
   = p "In superclass"
    1
  end
end
class Zoo2 < Zoo1
  def bar
    p "in Zoo2mod #{self}"
    s= uper + 1
  end

  mod =3D Module.new do
  &= nbsp; define_method(:bar, Zoo2.instance_method(:bar))
  end
&nbs= p; include mod
 
  def bar
    p "I= n bar"
    super + 1
  end
end

p Zoo2.new.bar
=
The above produces SystemStackError: stack level too deep, infinite-loo= ping 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 Oli= ver 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 existin= g methods without being forced to resort to aliasing. Here's an impleme= ntation 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
Develope= r | Engine Yard
(ph) 718.877.1325
--000e0cd248fa687e0a0460c9fcc0--