From: dblack@... Date: 2006-12-22T00:57:46+09:00 Subject: Re: extend weirdness? Hi -- On Fri, 22 Dec 2006, Ian White wrote: > 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< 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< 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 -- 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)