Dagnan
(Dagnan)
28 January 2011 14:45
1
Hi.
I'm trying to alias a method in a module and then overwriting this method (still having access to the old method).
I tried the following code that does not seem to work with Ruby 1.9.2. Do you have an idea why?
Thanks.
class A
def foo
puts 'bar'
end
end
module Foo
def self.included(base)
base.class_eval do
alias_method :old_foo, :foo #unless method_defined?(:old_foo)
end
end
def foo
puts 'foobar'
#old_foo
end
end
A.send :include, Foo
a = A.new
a.foo #=> bar
botp1
(botp)
29 January 2011 05:10
2
try
class A
def foo
puts 'bar'
end
end
module Foo
def self.included(base)
base.class_eval do
alias_method :old_foo, :foo #unless method_defined?(:old_foo)
end
end
def initialize(*args)
self.extend Foo::Overrider
end
module Overrider
def foo
puts 'foobar'
#old_foo
end
end
end
A.send :include, Foo
a = A.new
a.foo #=> foobar
a.old_foo #=>bar
not just sure if that is the best way for modifying a class instance
methods. i'd rather just use require if possible ...
best regards -botp
···
On Fri, Jan 28, 2011 at 10:45 PM, Dagnan <dagnan@gmail.com> wrote:
I'm trying to alias a method in a module and then overwriting this method (still having access to the old method).
As of Ruby 1.9, when you include a module M in a class C, an anonymous
class is created and becomes the immediate superclass of C and subclass
of C's original superclass. All instance methods of M will be inherited
by C in the same old way. So it is actually M#foo who gets overridden
(by its subclass C#foo); C#foo never gets redefined. This is how Ruby
currently resolves name conflicts raised during mixin.
If you call `super' in C#foo, it will route to M#foo.
class A
def foo
puts 'bar'
super
end
end
module Foo
def foo
puts 'foobar'
end
end
A.send :include, Foo
a = A.new
a.foo # => bar\nfoobar
···
--
Posted via http://www.ruby-forum.com/ .
Dagnan
(Dagnan)
1 February 2011 15:31
4
Thank you all for your answers.
Remix and Prepend have not been updated since a few months. candlerb and bot Peña solution are interesting.
Looks like when you include module Foo, the definition of foo in the
class still takes precedence over the one in the newly-included module.
This seems to work though:
class A
def foo
puts 'bar'
end
end
module Foo
def self.included(base)
base.class_eval do
alias_method :old_foo, :foo
def foo
puts 'foobar'
old_foo
end
end
end
end
A.send :include, Foo
a = A.new
a.foo
···
--
Posted via http://www.ruby-forum.com/ .
Su Zhang wrote in post #978699:
class A
def foo
puts 'bar'
super
end
end
module Foo
def foo
puts 'foobar'
end
end
A.send :include, Foo
a = A.new
a.foo # => bar\nfoobar
It's the same in 1.8.7.
I think the OP was looking for a way to achieve the opposite behaviour:
to import a module which would override the method in the class.
···
--
Posted via http://www.ruby-forum.com/\ .
John Mair (banisterfiend) has written some code to manipulate ancestor
chains, two of which are Remix and Prepend:
Remix: GitHub - banister/remix: Ruby modules re-mixed and remastered
Prepend: GitHub - banister/prepend: prepends modules in front of a class; so method lookup starts with the module
Prepend should do exactly what you're looking for.
···
On Mon, Jan 31, 2011 at 6:06 PM, Brian Candler <b.candler@pobox.com> wrote:
I think the OP was looking for a way to achieve the opposite behaviour:
to import a module which would override the method in the class.