From: dblack@... Date: 2006-07-11T09:25:13+09:00 Subject: Re: include vs. extend Hi -- On Tue, 11 Jul 2006, Daniel DeLorme wrote: > I was under the impression that include and extend were basically > module-level and object-level versions of the same thing, that including a > module at the class level had the same effect as extending an object. But it > seems there is a big difference: > > class Foo > include Enumerable > end > class Bar > def initialize > extend Enumerable > end > end > (class << Foo.new;self;end).ancestors #=> [Foo, Enumerable, Object, Kernel] > (class << Bar.new;self;end).ancestors #=> [Enumerable, Bar, Object, Kernel] > > This makes a whole world of difference when you want to wrap certain methods > with additional functionality. In such cases you *have* to use extend (or > ugly techniques like aliasing the old method). Why the difference? In what > cases should I use include and what cases should I use extend? It's understood that if you extend an object, it's because you *want* to put the module ahead of the object's class in the method look-up path. Otherwise, you'd put the functionality you want in the class :-) By the same token, it would be very unusual to put extend in initialize. Basically you use extend when you want to control behavior via modules on a per-object basis. A common use is for classes: module M def meth puts "Hi" end end class C extend M end C.meth # Hi obj.extend(Mod) is equivalent to: class << obj include Mod end (or very nearly equivalent; there may be some arcane difference I'm not remembering). So it's all really include operations -- but, when done with extend, the class doing the including is a singleton class. David -- http://www.rubypowerandlight.com => Ruby/Rails training & consultancy http://www.manning.com/black => RUBY FOR RAILS, the Ruby book for Rails developers http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log dblack@wobblini.net => me