This code:
module Foo
def self.included(base)
base.class_eval <<-end_eval
def self.meth
"Foo"
end
end_eval
end
end
module Bar
def self.included(base)
base.class_eval do
extend ClassMethods
end
end
module ClassMethods
def meth
"Bar"
end
end
end
class A
include Foo
include Bar
end
puts A.meth
produces:
Foo
whereas I would expect it to produce "Bar"
Can anyone explain what's going on here? i.e. Why the latter extend
with Bar doesn't over-write the class method introduced by Foo
The answer is simple: extend doesn't overwrite methods, it just
includes the module for the singleton object. As there is already a
singleton method 'meth' defined in the singleton object A, this method
is used systematically in method calls.
Does that explain your result ? For information, extend is
rb_extend_object(obj, module)
VALUE obj, module;
{
rb_include_module(rb_singleton_class(obj), module);
}
The previous post is using a rails-style idiom, which is unnecessarily
complex for the problem at hand.
Here's a simpler example to the same effect:
module Foo
def self.included(base)
class<<base
def meth
"Foo"
end
end
end
end
module Bar
def meth
"Bar"
end
end
class A
include Foo
extend Bar
end
puts A.meth
Which produces "Foo"
There's a workaround (remove the method by hand):
module Bar
def self.extended(base)
class<<base
remove_method :meth
end
end
end
But this workaround does what I'd expect Ruby to do (overwrite any
existing methods when extending)
I'm confused - is this expected behaviour?
Yes. When you send a message to A, it searches for a
corresponding method in:
its singleton class
modules mixed into its singleton class
its "birth class" (Class in this case)
modules mixed into its birth class
etc. (up to Object and Kernel)
in that order. When you do "extend Bar", you've inserted Bar as one
of the modules mixed into the singleton class of A (line 2). But when
you do include Foo, you insert the method "meth" directly into the
singleton class (line 1). Therefore, that version of "meth" will
always take priority, no matter how many modules you mix in or in what
order.
David
···
On Fri, 22 Dec 2006, Ian White wrote:
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)