[Q] best way to inject new functionality into a class

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?

Thanks for any insights and feedback.

cr

Hi --

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

···

On Wed, 8 Oct 2008, Chuck Remes wrote:

--
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!