From: Yehuda Katz Date: 2009-01-19T13:55:29+09:00 Subject: [ruby-core:21424] Re: Proposal: Module#copy_method --000e0cd247505185a20460cec014 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit MenTaLguY had a very good suggestion: modify alias_method so its second argument can be an unbound method. I like this solution a *lot*. -- Yehuda On Sun, Jan 18, 2009 at 4:14 PM, Yehuda Katz wrote: > 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 --000e0cd247505185a20460cec014 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable MenTaLguY had a very good suggestion: modify alias_method so its second arg= ument can be an unbound method. I like this solution a *lot*.

-- Yehuda

On Sun, Jan 18, 2009 at 4= :14 PM, Yehuda Katz <wycats@gmail.com> wrote:
Just = FYI, the define_method version fails if your method requires the use of sup= er. Observe:

class Zoo1
  def bar
    p "In superclas= s"
    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 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 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
Developer | Engine Yard
(ph) 7= 18.877.1325



--
Yehuda Katz=
Developer | Engine Yard
(ph) 718.877.1325
--000e0cd247505185a20460cec014--