[DPR] – Metaprogramming

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

Metaprogramming is an extremely extensive subject that deserves more than a simple review like this, so for those of you more interested, check out this blog post I made about the Ruby Object Model and Metaprogramming. But let’s move on to give just a taste of what metaprogramming is all about.

As you have seen throughout the Ruby implementations of the GoF patterns, some things get a lot easier due to Ruby’s dynamism and metaprogramming is just one of those things that you wouldn’t even dream about doing in static typed languages. A simple usage of metaprogramming that we will explore in this review is the ability to alter the insides of a class at runtime.

In Ruby, instead of writing getters and setters to read/write instance variables, we call a method called attr_accessor and pass it some symbols. Turns out that we can accomplish this same feat with the use of metaprogramming. We’ll call our version ‘accessors’:

class Object
	def self.accessors(*names)
		names.each do |name|
			class_eval %Q!
				def #{name}
					@#{name}
				end

				def #{name}=(val)
					@#{name} = val
				end
			!		
		end		
	end
end

class Person
	accessors :name, :age

	def initialize(name, age)
		@name = name
		@age = age
	end
end

pedro = Person.new('Pedro', 19)

puts pedro.name
puts pedro.age

pedro.name = 'Pedro Mateus Tavares'

puts pedro.name

In this code we directly alter the Object class to make our accessor usable by any object, then we open that class and pass it a string to evaluate into Ruby code. This way we ease the burden of people willing to use our code, of course not in this case since there already is attr_accessor, but it’s not hard to find practical uses of this.

A clear example is ActiveRecord, where you gain navigation through related objects simply by declaring a statement such as:

class Post < ActiveRecord::Base
	has_many :comments
end

With a simple line of code we gain easy access to a post’s comments, all thanks to metaprogramming. If you’re still not convinced, I highly suggest a read at the post mentioned in the beggining of this one.

Advertisements

[DPR] – Domain Specific Languages

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

Domain Specific Languanges, DSLs from now on, are languages that are meant (as the name says) to serve a specific domain. In general, people don’t understand programming languages, but what if we could use Ruby to create a special language that other people could understand, and more importantly, use without much dificulty?

As a quick example, RSpec, a testing framework, is a DSL by itself: its domain is testing, and when you look at an RSpec file, it doesn’t look like some complicated programming language, it looks alot like plain english, and most importantly, it makes perfect sense for testers. Here’s an example of RSpec taken directly from their homepage:

describe Bowling, "#score" do
  it "returns 0 for all gutter game" do
    bowling = Bowling.new
    20.times { bowling.hit(0) }
    bowling.score.should == 0
  end
end

DSLs, in a way, have the purpose of making a certain program make sense to non-programmers, and due to Ruby’s extremely light syntax rules, we can make that happen.

For the sake of simplicity, let’s code a small Agenda DSL that let’s someone plan their day and then get a pretty format of the whole schedule for the day. The best way to start is to actually code what you would like to see as the result, and then work your way back to make it all work, so something pretty neat for an Agenda could be like this:

Agenda.for :today do |schedule|
	schedule.this :morning do |add|
		add.task 'Take kids to school'
		add.reminder 'There is traffic on the highway'
		add.task 'Go to work'
	end
	schedule.this :afternoon do |add|
		add.task 'Go back to work'
		add.reminder 'Bring home dinner'
	end
	schedule.this :night do |add|
		add.task 'Work on side project'
		add.reminder'Dentist tomorrow'
	end
end

As you can see this is perfect readable code, you can actually follow a line of thought by reading through it. We could do alot better to make it even more syntax friendly, but for this example that will have to do. This DSL would ideally generate something like:

Day: 25/07/2010
------Morning schedule-----
REMEMBER:
**There is traffic on the highway**
Tasks:
 - Take kids to school
 - Go to work
------Afternoon schedule-----
REMEMBER:
**Bring home dinner**
Tasks:
 - Go back to work
------Night schedule-----
REMEMBER:
**Dentist tomorrow**
Tasks:
 - Work on side project

To generate that DSL is rather simple: the trick is to make use of alot of code blocks and code external methods (the ones a user will use) as much syntax friendly as possible, so there’s really not much of a formula to it like the common GoF patterns, you just have to code putting yourself in the place of a user who knows nothing about programming but wants to get something done. Anyway, if you studied your Ruby, you should have no trouble understanding this code:

class Agenda
	class << self
		alias_method :for, :new
	end
	
	def initialize(day)
		@tasks  = {:morning => '', :afternoon => '', :night => ''}
		@reminders = {:morning => '', :afternoon => '', :night => ''}
		puts "Day: #{Date.today.strftime("%d/%m/%Y")}" if day == :today
		yield(self)
	end
	
	def add_task(name, day_time)
		@tasks[day_time] += " - #{name}\n"
	end
	
	def add_reminder(name, day_time)
		@reminders[day_time] += "**#{name}**\n"
	end
	
	def this(daytime)
		puts "------#{daytime.to_s.capitalize} schedule-----\n"
		yield(DayTime.new(daytime, self))
		puts "REMEMBER:\n"
		puts @reminders[daytime]
		puts "Tasks:\n"
		puts @tasks[daytime]
	end
end

class DayTime
	def initialize(name, agenda)
		@name = name
		@agenda = agenda
	end
	
	def task(task)
		@agenda.add_task(task, @name)
	end
	
	def reminder(reminder)
		@agenda.add_reminder(reminder, @name)
	end
end

[DPR] – Builder Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

While the Factory Pattern is worried about which object to create, the Builder pattern is worried how to create it. Some objects require a load of work to be built and configured, and that’s what the Builder pattern eases out for us.

To illustrate the Builder pattern we’ll be using a simple Computer builder class:

class Computer
	attr_accessor :motherboard
	attr_accessor :display
	attr_accessor :drives

	def initialize(display=:crt, motherboard=Motherboard.new, drives=[])
		@motherboard = motherboard
		@drives = drives
		@display = display
	end
end

As you can see, the Computer object has a few pieces that need to be built, so let’s code them:

class CPU
	def process
		puts "I'm processing"
	end
end

class Motherboard
	attr_accessor :cpu
	attr_accessor :memory_size

	def initialize(cpu=CPU.new, memory_size=1000)
		@cpu = cpu
		@memory_size = memory_size
	end
end

class Drive
	attr_reader :type
	attr_reader :size
	attr_reader :writable

	def initialize(type, size, writable)
		@type = type
		@size = size
		@writable = writable
	end
end

As you can see, even with a simple layout like this one, creating a Computer object is still some cumbersome code:

motherboard = Motherboard.new(CPU.new, 2000)
drives = []
drives << Drive.new(:hard_drive, 200000, true)
drives << Drive.new(:cd, 760, true)
drives << Drive.new(:dvd, 4700, false)

computer = Computer.new(:lcd, motherboard, drives)
puts computer.inspect

To make this process simpler and more intuitive, we could use a builder:

class ComputerBuilder
	attr_reader :computer

	def initialize
		@computer = Computer.new
	end

	def display=(display)
		@computer.display = display
	end

	def memory_size=(size_in_mb)
		@computer.motherboard.memory_size = size_in_mb
	end
	
	def add_cd(writer=false)
		@computer.drives << Drive.new(:cd, 760, writer)
	end

	def add_dvd(writer=false)
		@computer.drives << Drive.new(:dvd, 4000, writer)
	end

	def add_hard_disk(size_in_mb)
		@computer.drives << Drive.new(:hard_disk, size_in_mb, true)
	end
end

Now all we need to do is create an instance of builder and call a few methods on it:

builder = ComputerBuilder.new
builder.add_cd(true)
builder.add_dvd
builder.add_hard_disk(10000)

puts builder.computer.inspect

In terms of lines of code we didn’t gain much (in this simple example), but in terms of code clarity we gained alot, and the fact that we could add much more complex creation code inside our builder and configure it with a single line of code is a big win.

Turns out we can also shorten the lines of code by using a technique called magic methods, which uses the same method_missing method we saw on the Proxy Pattern:

def method_missing(name, *args)
	words = name.to_s.split("_")
	return super(name, *args) unless words.shift == 'add'
	words.each do |word|
		next if word == 'and'
		add_cd if word == 'cd'
		add_dvd if word == 'dvd'
		add_hard_disk(100000) if word = 'harddisk'
	end	
end

By adding this to the ComputerBuilder method we can use methods such as this one:

builder = ComputerBuilder.new
builder.add_cd_and_dvd_and_harddisk

Whoever is familiar with Ruby on Rails should have noticed that this is also used by find methods such as find_by_name_and_email.

[DPR] – Factory and Abstract Factory Patterns

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

The Factory pattern is basically the Template Method applied to object creation, so, instead of choosing which kind of algorithm we want to use, we’ll be choosing what kind of object we want to create.

As you can see, the class diagram looks alot like the Template Method diagram, with the difference of each concrete factory creating a concrete product. To illustrate this we’ll be using a life simulator class called Pond.

#Factories (ponds)
class Pond
	def initialize(number_animals)
		@animals = []
		number_animals.times {|i| @animals << new_animal("Animal #{i}")}
	end

	def simulate_one_day
		@animals.each{|animal| animal.live}
	end
end

class DuckPond < Pond
	def new_animal(name)
		Duck.new(name)
	end
end

class FrogPond < Pond
	def new_animal(name)
		Frog.new(name)
	end
end

#Products (animals)

class Animal
	attr_accessor :name
	def initialize(name)
		@name = name
	end
end

class Frog < Animal
	def live
		puts "Frog #{self.name} is croaking peacefully."
	end
end

class Duck < Animal
	def live
		puts "Duck #{self.name} is quacking like there's no tomorrow."
	end
end

frog_pond = FrogPond.new(3)
frog_pond.simulate_one_day

duck_pond = DuckPond.new(3)
duck_pond.simulate_one_day

All this code is doing is letting the Pond subclasses decide which kind of object they should create.

In Ruby, even classes are objects, so we can pass them around however we like and call methods on them whenever we like, such as new. With that in mind, we can pass in class names (which are treated as Constants in Ruby) to the Pond constructor and create objects directly from it without depending on any factory subclasses, like so:

#Factories (ponds)
class Pond
	def initialize(number_animals, animal_class)
		@animal_class = animal_class
		@animals = []
		number_animals.times {|i| @animals << new_animal("Animal #{i}")}
	end

	def new_animal(name)
		@animal_class.new(name)
	end

	def simulate_one_day
		@animals.each{|animal| animal.live}
	end
end

Let’s move on to something bigger, say we now to simulate entire Habitats with animals and plants too, so we’re not gonna be generating random animals and plants, we have to follow nature’s way and put them in their right habitats. Notice we’re changing our intent from simply choosing which kind of object to create to choosing the right set of objects to create, that’s where the Abstract Factory comes in:

Each concrete factory is responsible for creating its own collection of objects, and that’s exactly what we’ll be doing with our Habitat example. First let’s create the products (plants and animals):

class Plant
	attr_accessor :name
	def initialize(name)
		@name = name
	end
end

class Algae < Plant
	def grow
		puts "Algae #{self.name} grows while floating in the water"
	end
end

class Tree < Plant
	def grow
		puts "Tree #{self.name} grows tall"
	end
end

class Animal
	attr_accessor :name
	def initialize(name)
		@name = name
	end
end

class Frog < Animal
	def live
		puts "Frog #{self.name} is croaking peacefully."
	end
end

class Tiger < Animal
	def live
		puts "Tiger #{self.name} roars fiercely"
	end
end

Now that we have all our products we can start coding habitats, which will be responsible for creating their own type of plant and animal:

class Habitat
	def initialize(number_animals, number_plants, organism_factory)
		@organism_factory = organism_factory
		@animals = []
		number_animals.times {|i| @animals << @organism_factory.new_animal("Animal #{i}")}
		@plants = []
		number_plants.times {|i| @plants << @organism_factory.new_plant("Plant #{i}")}
	end

	def simulate_one_day
		@animals.each{|animal| animal.live}
		@plants.each{|plant| plant.grow}
	end
end

class PondOrganismFactory
	def new_animal(name)
		Frog.new(name)
	end
	def new_plant(name)
		Algae.new(name)
	end
end

class JungleOrganismFactory
	def new_animal(name)
		Tiger.new(name)
	end
	def new_plant(name)
		Tree.new(name)
	end
end


jungle = Habitat.new(1,4, JungleOrganismFactory.new)
jungle.simulate_one_day

pond = Habitat.new(2,4, PondOrganismFactory.new)
pond.simulate_one_day

As you can see, we’re delegating the duty of creating objects to another object through composition, so, when you think about it, the same way the Factory Method is a specialization of the Template Method, the Abstract Factory is a specialization of the Strategy pattern.
Moving on, the same technique we used to elimite factory subclasses before we can use again to eliminate these. Remember, classes are just objects:

class OrganismFactory
	def initialize(animal_class, plant_class)
		@animal_class = animal_class
		@plant_class = plant_class
	end
	def new_animal(name)
		@animal_class.new(name)
	end
	def new_plant(name)
		@plant_class.new(name)
	end
end


jungle = Habitat.new(1,4, OrganismFactory.new(Tiger, Tree))
jungle.simulate_one_day

pond = Habitat.new(2,4, OrganismFactory.new(Frog, Algae))
pond.simulate_one_day

The important thing to remember about both patterns is how they’re different and how they’re alike. The main difference between them is their intent: the Factory Pattern is only worried about a single object to create while the Abstract Factory thinks of what collection of objects to create. In the other hand, they’re alike in the sense that both patterns focus on object creation.

[DPR] – Singleton Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

An object of which is permitted only a single instance with global access is a Singleton, simple as that. If you must have only one instance of a class and be able to access that instance from anywhere, then you’re applying the Singleton pattern.

Since anything that must be unique is a Singleton, let’s use myself is an example. I sure don’t want other instances of Me walking around.

class Pedro
	@@instance = Pedro.new

	def age
		puts Time.now.year - 1990 #poor age calculation ftw
	end

	def self.instance
		@@instance
	end

	private_class_method :new
end
begin
	#this won't work
	p = Pedro.new 
	p.age
rescue
	#but this will
	Pedro.instance.age
end

The code is simple, we’re using a class variable to hold an instance of Pedro and turning the method new private, so there’s no way to create other instances of Pedro, you have to call Pedro.instance to get its instance and work from that.
To make things simpler, Ruby ships with a Singleton module so you don’t have to write any code regarding the Singleton pattern, so let’s refactor our previous code to use that instead:

require 'singleton'
class Pedro
	include Singleton

	def age
		puts Time.now.year - 1990 #poor age calculation ftw
	end
end
begin
	#this won't work
	p = Pedro.new 
	p.age
rescue
	#but this will
	Pedro.instance.age
end

[DPR] – Decorator Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

Decorators are basically objects that ride on top of other objects with the intent of adding some functionality to them.

More formally speaking, the object and its decorators share a same interface, but the decorators hold a reference to the original object and override the shared method with some new things.

With that said, let’s write a simple class that writes a sentence and some decorators to ‘decorate’ that sentence with more funcionality.

class Writer
	def write(sentence)
		puts sentence
	end
end

writer = Writer.new
writer.write('hi')

class TimeDecorator
	def initialize(writer)
		@writer = writer
	end

	def write(sentence)
		@writer.write(Time.now.to_s + ': '+ sentence)
	end
end

time_writer = TimeDecorator.new(Writer.new)
time_writer.write('hi')

class SizeDecorator
	def initialize(writer)
		@writer = writer
	end

	def write(sentence)
		@writer.write(sentence + " |size: #{sentence.size}|")
	end
end


big_object = SizeDecorator.new(TimeDecorator.new(Writer.new))
big_object.write('hi')

Since we’re basically incrementing behavior, we could take advantage of Ruby’s mixins support: modules. This way we can dynamically extend objects with any module:

class Writer
	def write(sentence)
		puts sentence
	end
end

writer = Writer.new
writer.write('hi')

module TimeDecorator
	def write(sentence)
		super(Time.now.to_s + ': '+ sentence)
	end
end

writer.extend TimeDecorator
writer.write('hi')

module SizeDecorator
	def write(sentence)
		super(sentence + " |size: #{sentence.size}|")
	end
end

writer.extend SizeDecorator
writer.write('hello')

The Ruby on Rails framework has a pretty cool implementation of the Decorator pattern with the method called alias_method_chain, where it takes a method and renames it with some new functionality.

[DPR] – Proxy Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

A Proxy is like an impostor. Much like the Adapter, it stands in the way between a client and the real object, which is useful when you need to create a protection barrier on your object without having to pollute it with authorization code, or when your object is really big and is on the other side of the world, so you want to delay at most any request to it.
Similar to the Adapter, the Proxy Pattern is heavily built on top of object composition and delegation, since it’s just a ‘fake’ object who passes over requests to a real object.

Let’s start with the protection proxy in the context of a BankAccount class, where you’d need the user to have permission to access his account. First, the BankAccount class:

class BankAccount
	attr_reader :balance
	
	def initialize(starting_balance = 0)
		@balance = starting_balance
	end
	
	def deposit(amount)
		@balance += amount
	end
	
	def withdraw(amount)
		@balance -= amount
	end
end

And now the proxy:

class AccountProtectionProxy
	def initialize(real_account, owner_name)
		@subject = real_account
		@owner_name = owner_name
	end
	
	def deposit(amount)
		check_access
		@subject.deposit(amount)
	end
	
	def withdraw(amount)
		check_access
		@subject.withdraw(amount)
	end
	
	def balance
		check_access
		@subject.balance
	end
	
	def check_access
		#for the sake of simplicity
		raise 'Not permitted'  unless @owner_name == 'pedro'
	end
end

proxy = AccountProtectionProxy.new(BankAccount.new, 'pedro')
proxy.deposit(50)
puts proxy.balance

We’re making sure on each method that the user has permission, and putting this code in the BankAccount class itself wouldn’t make sense (and would cause horrible coupling) since it’s not a bank account’s duty to deal with permissions, it should only deal with operations related to money, so we shove all the permission mess into a proxy, which works perfectly.

Now we’ll look at the virtual proxy, which delays creation of an object until he’s really needed, which is required when you have an object standing across a network and is expensive to be creating all the time. Sticking with the BankAccount class, let’s create a new proxy for it:

class VirtualAccountProxy
	def initialize(starting_balance=0)
		@starting_balance = starting_balance
	end
	
	def deposit(amount)
		subject.deposit(amount)
	end
	
	def withdraw(amount)
		subject.withdraw(amount)
	end
	
	def balance
		subject.balance
	end
	
	def subject
		@subject ||= BankAccount.new(@starting_balance)
	end
end

account = VirtualAccountProxy.new
account.deposit(50)
puts account.balance

A problem with this implementation of the virtual proxy is that the account object is being created inside it, which kind of couples the proxy to the BankAccount class. We can avoid this with the use of code blocks:

class VirtualProxy
	def initialize(&block)
		@block = block
	end
	
	#other methods
	
	def subject
		@subject ||= @block.call
	end
	
end

account = VirtualProxy.new {BankAccount.new}
account.deposit(50)
puts account.balance

One of the disavantages of the Proxy pattern is that you have to write a bunch of ‘decoy’ methods, such as the ones I omitted at this last piece of code, code that might not seem much for our little BankAccount class, but that would be a hassle with classes such as String with 142 methods or Array with 118. This is where Ruby shines.

When you call for a method that Ruby doesn’t find, it looks for a method named ‘method_missing’, which, if you don’t define yourself, is defined in the Object class from which every object in Ruby extends from. With that knowledge, we can define our own method_missing and redirect any method to the original object. Let’s refactor our virtual proxy to use this technique instead:

class VirtualProxy
	def initialize(&block)
		@block = block
	end
	
	def method_missing(name, *args)
		subject.send(name, *args)
	end
	
	def subject
		@subject ||= @block.call
	end
end
account = VirtualProxy.new {BankAccount.new}
account.deposit(50)
puts account.balance

What’s happening is:

  1. You call deposit(50), which the VirtualProxy class doesn’t know about.
  2. Since there’s no such method in our class, then Ruby searches for a method_missing method and passes it the name of the method that was called along with its parameters.
  3. We defined method_missing, telling it to send basically any incoming method to our subject.

And since our proxy is so decoupled from any implementation, we can use it with basically any class, such as Array:

array = VirtualProxy.new {  [] }
array << 'hello world'
puts array.first

The downside of this technique is performance. Since Ruby has to look at the class’ whole method table first and then send the method to the real object, things do get a bit slower than it would if the method simply existed, so you’d end up trading messiness for perfomance, which compensates sometimes.

[DPR] – Adapter Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

An Adapter does what you might expect: it attaches itself into 2 ends which aren’t compatible between them. The classic analogy to this is a plug adapter, that thing you use to turn 3-way plugs compatible into a 2-way socket. Without the adapter, you’d be screwed and things just wouldn’t work, and it’s no different on software.

That class diagrams translates into this: the client thinks he’s talking to his target, but he’s actually talking to an adapter which redirects calls to the real target (adaptee). Let’s start simple with the plugs and sockets example, first we’ll try to fit in a 3-way plug into a 2-way socket:

class TwoWaySocket
	def initialize(plug)
		@plug = plug
	end
	
	def plug_in
		begin
			@plug.two_way_plug_in
		rescue
			puts "Plug doesn't fit!!"
		end
	end
end

class ThreeWayPlug
	def three_way_plug_in
		puts "All 3 pins plugged"
	end
end

socket = TwoWaySocket.new(ThreeWayPlug.new)
socket.plug_in

So I’m not lying, it really doesn’t fit. Adapters to the rescue!

class TwoWaySocket
	def initialize(plug)
		@plug = plug
	end
	
	def plug_in
		begin
			@plug.two_way_plug_in
		rescue
			puts "Plug doesn't fit!!"
		end
	end
end

class ThreeWayPlug
	def three_way_plug_in
		puts "All 3 pins plugged"
	end
end

class PlugAdapter
	def initialize(three_way_plug)
		@three_way_plug = three_way_plug
	end
	
	def two_way_plug_in
		@three_way_plug.three_way_plug_in
	end
end

#we'll now call a socket with the adapter instead
socket = TwoWaySocket.new(PlugAdapter.new(ThreeWayPlug.new))
socket.plug_in

As you can see, we’re just creating an object that matches one interface with the other so all things can work gracefully.

Now we get to the cool part where we do things the Ruby way. Instead of creating an intermediate class, we could…cheat! Yes, why use a plug adapter if we can get a screwdriver and open up the 3-way plug, remove a pin and adjust things inside so it’ll work with our 2-way socket. In real life that might seem hard, but in this case:

#make sure the original class is loaded
require 'three_way_plug'

class ThreeWayPlug
	def two_way_plug_in
		three_way_plug_in
	end
end

socket = TwoWaySocket.new(ThreeWayPlug.new)
socket.plug_in

There, we simply reopened the freakin’ class at runtime and said “you WILL have what the socket requires, you WILL fit!”. The cool thing about doing this is that you don’t have to change the code to use an adapter and you don’t have to create yet another class just to handle the situation, you just reopen and cirurgically change whatever you want.

Does changing the whole class seems too drastic? What if you wanted just that one object to adapt instead of everyone? No problem, Ruby gives you the power to edit instances much like you’d edit classes:

three_way_plug = ThreeWayPlug.new
socket = TwoWaySocket.new(three_way_plug)
socket.plug_in #this won't work

class << three_way_plug
	def two_way_plug_in
		three_way_plug_in
	end
end

socket.plug_in #but this will

Or if you think class << is scary, you can define a new method on the instance by putting the instance name before the method name:

three_way_plug = ThreeWayPlug.new
socket = TwoWaySocket.new(three_way_plug)
socket.plug_in #this won't work

def three_way_plug.two_way_plug_in
	three_way_plug_in
end

socket.plug_in #but this will

As usual, there are pros and cons about both ways. Class/instance redefition in certainly simpler and easier, but that's untrue when it comes to complex classes that you need to adapt, specially when you don't have a full understanding of that class, so, for those cases, stick with the classic, good ol' GoF way.

Case any of these last 2/3 chunks of code look unfamiliar to you, I suggest reading my post on the Ruby Object Model and Metaprogramming, it will help you understand and learn the powers of Ruby reflection, which is constantly used due to Ruby’s dynamic typing style.

[DPR] – Command Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

The Command pattern is nothing more than a standardization of methods: by keeping actions with a same name in multiple places you can ensure that by calling that specific method, something will happen. As you can deduce, delegation and composition play a big part here because the callers will use the objects they’re referencing, or as we might say, issue commands, by delegating the target object a certain method.

Let’s say we code a button class that does something when pushed and say we were hand out this button for other developers to use. Since we can’t predict every possible way the button will be used, we tell them ‘Hey, be sure to pass an object with an execute() method when creating my button’:

class Button
	attr_accessor :command
	
	def initialize(command)
		@command = command
	end
	
	def on_push
		@command.execute if @command
	end
end

This way we avoid supplying a blank on_push() method forcing developers to create a subclass of Button and overwrite it with that they need, which is the main purpose of the Command pattern. Anyway, let’s code the command itself:

class SomeRandomCommand
	def execute
		puts "Look! I've been executed :D"
	end
end

Dang that was hard. Let’s see it working:

b = Button.new(SomeRandomCommand.new)
#something happens and the button is pushed
b.on_push

And it gets even easier: a command is simply a chunk of code that gets executed when his time comes, which ironically is the same thing a block does! Let’s refactor our Button class to use blocks instead.

class Button
	attr_accessor :command
	def initialize(&command)
		@command = command
	end
	
	def on_push
		@command.call if @command
	end
end

b = Button.new do
	puts "Look! I've been executed :D"
end
	
#something happens and the button is pushed
b.on_push

Just like that we got rid of the whole need of creating command classes, which is kind of relative to what you’re doing, using blocks are fine for quick stuff but more complex logic should be stored in a more proper way (classes).

But the cool thing about commands is when you start recording each one of them giving you the ability to undo (and redo) them. Let’s refactor our little Button to be able to store and undo commands:

class Button
	attr_accessor :commands
	def initialize
		@commands = []
	end
	
	def on_push
		@commands.each{|c|c.execute if c}
	end
	
	def undo
		@commands.reverse.each{|c|c.unexecute}
	end
	
	def << (command)
		@commands << command
	end
		
end

class SomeRandomCommand
	def initialize(number)
		@number = number
	end
	
	def execute
		puts "Executing command number #{@number}."
	end
	
	def unexecute
		puts "Undoing command number #{@number}."
	end
end

b = Button.new

3.times do |n|
	b << SomeRandomCommand.new(n+1)
end
	
#something happens and the button is pushed
b.on_push

#oops, there was a mistake, undo everything
b.undo

Whoever’s familiar with Ruby on Rails should have noticed the similarity this has with migrations, they’re nothing more than commands that execute, get stored and have the ability to undo.

[DPR] – Iterator Pattern

This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

An Iterator is simply an object that provides a way to access the elements of a certain collection. If this iteration happens inside or outsite the collection, it depends on how you implement it. Since we’re gonna go deeper in internal iterators, let’s take a quick look at external iterators, which are objects that sweep you through a collection without knowing it’s insides:

class ArrayIterator
	def initialize(array)
		@array = array
		@index = 0
	end
	
	def has_next?
		@index < @array.length
	end
	
	def item
		@array[@index]
	end
	
	def next_item
		value = @array[@index]
		@index += 1
		value
	end
end

Using this code is dead simple, and due to Ruby’s dynamic typing we can use it on any object that has a length and a [] method, such as String:

#Array
i = ArrayIterator.new(['a', 'b','c'])
while i.has_next?
	puts i.next_item
end
#String
i2 = ArrayIterator.new('abc')
while i2.has_next?
	puts i2.next_item
end

It works and it doesn’t look like much to do, but let’s see how internal iterators are just way simpler. Internal iterators in Ruby work with blocks, you simply call an iterator method and pass it a block of code to execute at each member of the collection, and so the method will simply yield at each one. Let’s see how that works.

def for_each(array)
	i = 0
	while i < array.length
		yield(array[i])
		i+=1
	end
end

a = [1,2,3]

for_each(a) do |element|
	puts element
end

The thing is, you don’t build yourself internal iterators, you could, but why reinvent the wheel? Ruby ships with a powerful module called Enumerable which gives you a bunch of handy iterators, and all you need to do is include the module and define the basic iterator for it (each). Say you have a Tree and would like to iterate through its branches:

class Tree
	include Enumerable
	def initialize
		@branches = []
	end
	
	def each(&block)
		@branches.each(&block)
	end
	
	def <<(branch)
		@branches << branch
	end
end

tree = Tree.new
tree << 'branch1'
tree << 'branch2'
tree << 'branch3'

tree.each do |branch|
	puts branch
end

Of course that in most cases you do want to use an internal iterator since it’s so much simpler in terms of code, but knowing about external iterators can be interesting when things get dirty.
For instance, an advantage of using external iterators is that since you’re using someone else to sweep an object for you, changing the object won’t screw everything up because we’re only iterating case the next object in line is good to go, where in internal iterators you just force yourself through the next block without a single care.