From: "David A. Black" Date: 2008-10-08T04:29:17+09:00 Subject: Re: [Q] best way to inject new functionality into a class Hi -- On Wed, 8 Oct 2008, Chuck Remes wrote: > I've pretty much made up my mind how to modify my classes, but I thought I > would throw this issue out to the community at large to see if I'm missing > something glaringly obvious. > > When I write code for classes & modules that need to collaborate, I typically > inject the functionality of one into the other one of two ways (I rarely > subclass). My code will explain. > > #1 > > module Foo > def baz; # do something; end > end > > class Bar > include Foo # Bar takes on Foo's methods > end > > > #2 > > class Foo > def baz; # do something; end > end > > class Bar > attr_accessor :strategy # implement the strategy pattern > end > > bar = Bar.new > bar.strategy = Foo.new > > > Recent projects at work are forcing me to be a little more dynamic than #1 > can be, and #2 can be error-prone since there is a lot more setup & wire code > required. > > As I continue to explore the ruby language, I ran across another mechanism > for class modification. > > #3 > > module Foo > def baz; # do something; end > end > > class Bar > end > > bar = Bar.new > bar.extend(Foo) > > > This third way looks like the cleanest way of all. It has the added benefit > that "later" during runtime I could change my mind and replace the Foo module > with another one that implements the same methods. > > bar.extend(Baz) # overrides all methods with the same signature as Bar or Foo > > > Do you, in general, agree that using #extend is at least superior to #2? I think they all have their uses, but I'll mention that #extend has always been my favorite choice for modifying core functionality: module DifferentArray ... end a = [].extend(DifferentArray) etc. If you're writing your own classes then including a module in a class is quite legit and powerful. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL Advancing with Rails January 19-22 Fort Lauderdale, FL * * Co-taught with Patrick Ewing! See http://www.rubypal.com for details and updates!