Mixins

I am completely lost – it looks like it is not possible to redefine a method at all with a mixin:

class Test
def foo
puts "Test#foo"
end
end

module Mixin
def foo
puts "Mixin#foo"
end
def bar
puts "Mixin#bar"
end
end

class Test
include Mixin
end

Test.new.foo #==> Test#foo
Test.new.bar #==> Mixin#bar

So new method are added just fine, however a method I would like to redefine stays the same. Is it how it was supposed to work? And how to actually do redefine a method? Should there be any tricks involved, like aliasing?

Thank you,
Gennady

Gennady wrote:

I am completely lost – it looks like it is not possible to redefine a
method at all with a mixin:

class Test
def foo
puts “Test#foo”
end
end

module Mixin
def foo
puts “Mixin#foo”
end
def bar
puts “Mixin#bar”
end
end

class Test
include Mixin
end

Test.new.foo #==> Test#foo
Test.new.bar #==> Mixin#bar

So new method are added just fine, however a method I would like to
redefine stays the same. Is it how it was supposed to work? And how to
actually do redefine a method? Should there be any tricks involved, like
aliasing?

Test.ancestors #==> [Test, Mixin, Object, Kernel]

So actually, your Test#foo is replacing Mixin#foo, because Test occurs
before Mixin on the method search path.

class Test
def foo
super
end
end

Test.new.foo #==> Mixin#foo

Gennady wrote:

I am completely lost – it looks like it is not possible to redefine a
method at all with a mixin:

class Test
def foo
puts “Test#foo”
end
end

module Mixin
def foo
puts “Mixin#foo”
end
def bar
puts “Mixin#bar”
end
end

class Test
include Mixin
end

Test.new.foo #==> Test#foo
Test.new.bar #==> Mixin#bar

So new method are added just fine, however a method I would like to
redefine stays the same. Is it how it was supposed to work?

Yes, this is how it’s supposed to work. When you mix a module into a
class, the module more-or-less acts as a superclass of the class it’s
mixed-into. So for your example, Test#foo is redefining the Module#foo
method.

Thanks to everybody for explanation. My mistake was to expect something
happen magically. Now that I think how the whole mixin mechanism works I see
why modules and classes in my example behaved that way. It explains
everything. The bottom line is: when you want something done – do it
yourself ;-), that what append_features is there for.

Gennady.
(Thank you Lyle, too, for the off-list suggestion)

···

----- Original Message -----
From: “Joel VanderWerf” vjoel@PATH.Berkeley.EDU
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, January 21, 2003 10:52 AM
Subject: Re: Mixins

Gennady wrote:

I am completely lost – it looks like it is not possible to redefine a
method at all with a mixin:

class Test
def foo
puts “Test#foo”
end
end

module Mixin
def foo
puts “Mixin#foo”
end
def bar
puts “Mixin#bar”
end
end

class Test
include Mixin
end

Test.new.foo #==> Test#foo
Test.new.bar #==> Mixin#bar

So new method are added just fine, however a method I would like to
redefine stays the same. Is it how it was supposed to work? And how to
actually do redefine a method? Should there be any tricks involved, like
aliasing?

Test.ancestors #==> [Test, Mixin, Object, Kernel]

So actually, your Test#foo is replacing Mixin#foo, because Test occurs
before Mixin on the method search path.

class Test
def foo
super
end
end

Test.new.foo #==> Mixin#foo