[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

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

Chuck Remes

10/7/2008 7:21:00 PM

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


1 Answer

David A. Black

10/7/2008 7:29:00 PM

0

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.r... for details and updates!