My last post was about the strategy pattern. The strategy pattern is a great way to vary part of an algorithm, using composition of objects. Ruby allows for a variation on this technique; the variation is to use block objects.
Using blocks to vary part of an algorithm is very common in the Ruby community. It can improve the readability of your code and is particularly useful for creating DSLs.
Here is an example Report class. It looks similar to the one in the strategy pattern post but has been modified slightly to accept a block. The output_report method calls the block, passing in self to provide context.
class Report attr_reader :title, :text def initialize(&formatter) @title = 'Acme Inc Report' @text = ['Good stuff', 'What an awesome quater'] @formatter = formatter end def output_report @formatter.call(self) end end
Now we can initialize Report with a block. The block provides the part of the algorithm that we want to vary.
report = Report.new do |context| puts context.title context.text.each do |line| puts line end end
Finally, we can check the output.
report.output_report #=> Acme Inc Report #=> Good stuff #=> What an awesome quater
Implementing the strategy pattern using blocks is more idiomatic Ruby. It can make your code more readable and is great for implementing DSLs.