Tuesday, March 11, 2008

Ruby's Most Succinct Strategy Pattern Implementation Possible

I could be wrong about this but I believe I'm using it.

Here's how you set it up:



(The assumption here is alias :L :lambda.)

Here's how you use it:



Since you've got Procs as instance variables, swapping out the strategies is as easy as declaring

attr_accessor :strategy

and then saying

Widget.strategy = lambda {|*args| do(stuff)}

To invoke your strategy from within the Widget, just do

@strategy[]

or

@strategy[:foo => "bar"]

Design patterns remain useful in Ruby, but they become much, much more compact.

By the way, in the above code:



@when is assigned the value of running @next against a @queue. If you check the top of the page you'll see that @next is a Proc, which means you can modify dynamically how it computes the next value in the queue, simply by setting a new value for @next. But what's interesting is that @queue is a queue of Procs, and elsewhere in the code base there are calls to @when which leverage the fact that it's going to be a Proc.

This kind of system, where you have strategies for selecting strategies, could be unwieldy in many languages. It's smooth as silk in Ruby.