Thursday, February 28, 2008

Ruby: Replace method_missing with dynamic method definitions

You have methods you want to handle dynamically without the pain of debugging method_missing.

class Decorator
def initialize(subject)
@subject = subject
end

def method_missing(sym, *args, &block)
@subject.send sym, *args, &block
end
end

becomes

class Decorator
def initialize(subject)
subject.public_methods(false).each do |meth|
(class << self; self; end).class_eval do
define_method meth do |*args|
subject.send meth, *args
end
end
end
end
end

Motivation

Debugging classes that use method_missing can often be painful. At best you often get a NoMethodError on an object that you didn't expect, and at worst you get stack level too deep (SystemStackError).

There are times that method_missing is required. If the usage of an object is unknown, but must support unexpected method calls you may not be able to avoid the use of method_missing.

However, often you know how an object will be used and using Dynamically Define Method you can achieve the same behavior without relying on method_missing.

Mechanics
  • Dynamically define the necessary methods
  • Remove method_missing
  • Test
Example: Dynamic delegation without method_missing

Delegation is a common task while developing software. Delegation can be handled explicitly by defining methods yourself or by utilizing something from the Ruby Standard Library such as Forwardable. Using these techniques gives you control over what methods you want to delegate to the subject object; however, sometimes you want to delegate all methods without specifying them. Ruby's Standard Library also provides this capability with the delegate library, but we'll assume we need to implement our own for this example.

The simple way to handle delegation (ignoring the fact that you would want to undefine all the standard methods a class gets by default) is to use method_missing to pass any method calls straight to the subject.

class Decorator
def initialize(subject)
@subject = subject
end

def method_missing(sym, *args, &block)
@subject.send sym, *args, &block
end
end

This solution does work, but it can be problematic when mistakes are made. For example, calling a method that does not exist on the subject will result in the subject raising a NoMethodError. Since the method call is being called on the decorator, but the subject is raising the error it may be painful to track down where the problem resides.

The wrong object raising a NoMethodError is significantly better than the dreaded stack level too deep (SystemStackError). This can be caused by something as simple as forgetting to use the subject instance variable and trying to use a non-existent subject method or any misspelled method. When this happens the only feedback you have is that something went wrong, but Ruby isn't sure exactly what it was.

These problems can be avoided entirely by using the available data to dynamically define methods at run time. The following example defines an instance method on the decorator for each public method of the subject.

class Decorator
def initialize(subject)
subject.public_methods(false).each do |meth|
(class << self; self; end).class_eval do
define_method meth do |*args|
subject.send meth, *args
end
end
end
end
end

Using this technique any invalid method calls will be correctly reported as NoMethodErrors on the decorator. Additionally, there's no method_missing definition, which should help avoid the stack level too deep problem entirely.

Example: Using user defined data to define methods

Often you can use the information from a class definition to define methods instead of relying on method_missing. For example, the following code relies on method_missing to determine if any of the attributes are nil.

class Person
attr_accessor :name, :age

def method_missing(sym, *args, &block)
empty?(sym.to_s.sub(/^empty_/,"").chomp("?"))
end

def empty?(sym)
self.send(sym).nil?
end
end

The code works, but it suffers from the same debugging issues that the previous example does. Utilizing Dynamically Define Method the issue can be avoided by defining the attributes and creating the empty_attribute? methods at the same time.

class Person
def self.attrs_with_empty_methods(*args)
attr_accessor *args

args.each do |attribute|
define_method "empty_#{attribute}?" do
self.send(attribute).nil?
end
end
end

attrs_with_empty_methods :name, :age
end

Monday, February 25, 2008

Ruby: Dynamically Define Method

Defining Methods Dynamically

You have methods that can be defined more concisely if defined dynamically.

def failure
self.state = :failure
end

def error
self.state = :error
end

becomes

def_each :failure, :error do |method_name|
self.state = method_name
end

Motivation

I use Dynamically Define Method quite frequently. Of course, I default to defining methods explicitly, but at the point when duplication begins to appear I quickly move to the dynamic definitions.

Dynamically defined methods can help guard against method definition mistakes, since adding another method usually means adding one more argument; however, this is not the primary reason for Dynamically Define Method.

The primary goal for Dynamically Define Method is to more concisely express the method definition in a readable and maintainable format.

Mechanics
  • Dynamically define one of the similar methods
  • Test
  • Convert the additional similar methods to use the dynamic definition
  • Test
Example: Using def_each do define similar methods.

Defining several similar methods is verbose and often unnecessary. For example, each of the following methods is simply changing the value of the instance variable state.

def failure
self.state = :failure
end

def error
self.state = :error
end

def success
self.state = :success
end

The above code executes perfectly well, but it's too similar to justify 11 lines in our source file. The following example could be a first step to removing the duplication.

[:failure, :error, :success].each do |method|
define_method method do
self.state = method
end
end

Dynamically defining methods in a loop creates a more concise definition, but it's not a particularly readable one. To address this issue I define the def_each method. The motivation for defining a def_each method is that it is easy to notice and understand while scanning a source file.

class Class
def def_each(*method_names, &block)
method_names.each do |method_name|
define_method method_name do
instance_exec method_name, &block
end
end
end
end
The instance_exec method

Ruby 1.9 includes instance_exec by default; however, Ruby 1.8 has no such feature. To address this limitation I generally include the following code created by Mauricio Fernandez.

class Object
module InstanceExecHelper; end
include InstanceExecHelper
def instance_exec(*args, &block)
begin
old_critical, Thread.critical = Thread.critical, true
n = 0
n += 1 while respond_to?(mname="__instance_exec#{n}")
InstanceExecHelper.module_eval{ define_method(mname, &block) }
ensure
Thread.critical = old_critical
end
begin
ret = send(mname, *args)
ensure
InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
end
ret
end
end
With def_each now available I can define the methods similar to the example below.

def_each :failure, :error, :success do |method_name|
self.state = method_name
end

Example: Defining instance methods with a class method.

The def_each method is a great tool for defining several similar methods, but often the similar methods represent a concept that can be used within code to make the code itself more descriptive.

For example, the previous method definitions were all about setting the state of the class. Instead of using def_each you could define a states class method that would generate the state setting methods. Defining a states class method helps create more expressive code.

def error
self.state = :error
end

def failure
self.state = :failure
end

def success
self.state = :success
end

becomes

class Post
def self.states(*args)
args.each do |arg|
define_method arg do
self.state = arg
end
end
end

states :failure, :error, :success
end

Example: Defining methods by extending a dynamically defined module

Sometimes you have an object and you simply want to delegate method calls to another object. For example, you might want your object to decorate a hash so that you can get values by calling methods that match keys of that hash.

As long as you know what keys to expect, you could define the decorator explicitly.

class PostData
def initialize(post_data)
@post_data = post_data
end

def params
post_data[:params]
end

def session
post_data[:session]
end
end

While this works, it's truly unnecessary in Ruby. Additionally, it's a headache if you want to add new delegation methods. You could define method_missing to delegate directly to the hash, but I find debugging method_missing problematic and avoid it when possible. I'm going to skip straight to defining the methods dynamically from the keys of the hash. Let's also assume that the PostData instances can be passed different hashes, thus we'll need to define the methods on individual instances of PostData instead of defining the methods on the class itself.

class PostData
def initialize(post_data)
(class << self; self; end).class_eval do
post_data.each_pair do |key, value|
define_method key.to_sym do
value
end
end
end
end
end

The above code works perfectly well, but it suffers from readability pain. In cases like these I like to take a step back and look at what I'm trying to accomplish.

What I'm looking for is the keys of the hash to become methods and the values of the hash be returned by those respective methods. The two ways to add methods to an instance are to define methods on the metaclass and to extend a module.

Luckily for me, Ruby allows me to define anonymous modules. I have a hash and a decorator, but what I want is a way to define methods of the decorator by extending a hash, so I simply need to convert the hash to a module.

The following code converts a hash to a module with a method for each key that returns the associated value.

class Hash
def to_mod
hash = self
Module.new do
hash.each_pair do |key, value|
define_method key do
value
end
end
end
end
end

With the above code in place, it's possible to define the PostData class like the example below.

class PostData
def initialize(post_data)
self.extend post_data.to_mod
end
end

Sunday, February 24, 2008

Pair Programming all the time

I was having a discussion with a friend a few days ago about Pair Programming. I am, obviously, an advocate, but my friend doesn't believe in it.

Many people do not believe in Pair Programming (pairing). Most of those people don't agree with the benefits of pairing. However, my friend does believe that pairing is beneficial, he just does not believe in pairing all the time.

This is where semantics become very important. He was defining all the time as every minute that you are at work. I define all the time (in terms of pairing) as when I'm writing code that I'm going to commit.

There's plenty of time in the day that I spend on my own. Here's a few examples, but it's not representative of everything I do solo.
  • Read about a library that might help us later on.
  • Spike a new way to solve a complex problem.
  • Debug a tricky issue.
Each of the above tasks I often take on without a pair. Usually I end up asking for help while I'm working alone, or I ask for someone to review my conclusions, but I don't force myself to pair when I'm not sure what direction I'm headed in.

Patrick Kua talks about working in two different modes, Experimental and Focused, in the context of Test Driven Development. I agree with Patrick and I believe the discussion also directly applies to Pair Programming. When you know what you want to get done, pairing ensures that you do it well. But, when you don't know what you need to do, it's generally a pain to try to talk through the problem with your pair. Talking through a problem can be helpful, but I often like to get a decent understanding before trying to explain it to someone else. I also like to be able to stop going in one direction and immediately switch to another if I spot something interesting.

Pair programming is a good thing, but like all good things, it's best when done in moderation. There are times when you do not need to pair, and Wikipedia has a decent list of reasons that people are opposed to pair programming. But, those things should not discourage you from giving Pair Programming a fair shot.

Given the right set up and approach, I believe pairing is the most efficient way to deliver quality software.

Ruby: Inline Rescue

On my current project we use action specific Presenters 20% of the time. We opened ActionController and ActionView and redefined the render methods to automatically create presenters based on convention. For example the CommentsController has a show action, so render will try to create Comments::ShowPresenter when the show action is rendered. This works well for us, but like I said we only need a specific presenter 20% of the time. The other 80% of the time we still want a presenter that contains basic methods necessary on each page, but it is not specific to an action.

We solved this issue by attempting to create the specific presenter and rescuing with the base presenter.

klass = "#{action}_presenter".camelize.constantize rescue Presenter
@presenter = klass.new

Inline rescues promote concise code, but they shouldn't be overused to create overly complex lines of code. For example, I probably could have combined the two lines above into one line, but that would be a bit much to digest in my opinion.

In the example we attempt to create the class using constantize, but if an error (like uninitialized constant) occurs we rescue with the base Presenter class. Either way, the result is assigned to the klass local variable.

Ruby: Creating Anonymous Classes

Classes in Ruby are first-class objects—each is an instance of class Class. -- ruby-doc.org
Most classes are defined using the syntax of the following example.

class Person
...
end

Defining classes this way is familiar to most developers. Ruby provides another syntax for defining classes using Class.new. The following example also defines the Person class.

Person = Class.new do
...
end
Class.new(super_class=Object) creates a new anonymous (unnamed) class with the given superclass (or Object if no parameter is given). You can give a class a name by assigning the class object to a constant. -- ruby-doc.org
The following example shows that the new class begins as an anonymous Class instance, but becomes a named class when it's assigned to a constant.

klass = Class.new
klass.ancestors # => [#<Class:0x21b38>, Object, Kernel]
klass.new.class # => #<Class:0x21b38>

Person = klass
Person.ancestors # => [Person, Object, Kernel]
Person.new.class # => Person

klass.ancestors # => [Person, Object, Kernel]
klass.new.class # => Person
klass # => Person

I generally use traditional syntax when defining named classes, but I have found anonymous classes very helpful when creating maintainable tests. For example, I often need to test instance methods of a Module. The following tests show how you can define a class, include a module, and assert the expected value all within one test method.

require 'test/unit'

module Gateway
def post(arg)
# implementation...
true
end
end

class GatewayTest < Test::Unit::TestCase
def test_post_returns_true
klass = Class.new do
include Gateway
end
assert_equal true, klass.new.post(1)
end
end

There are other ways to solve this issue, but I prefer this solution because it keeps everything necessary for the test within the test itself.

Another advantage to defining classes using Class.new is that you can pass a block to the new method; therefore, the block could access variables defined within the same scope. In practice, I've never needed this feature, but it's worth noting.

Tuesday, February 19, 2008

Rake: Task Overwriting

Update at bottom

By default Rake Tasks append behavior every time they are defined. The following example shows that both definitions are executed.

require 'rubygems'
require 'rake'

task :the_task do
p "one"
end

task :the_task do
p "two"
end

Rake::Task[:the_task].invoke
# >> "one"
# >> "two"

I like this behavior, but sometimes you want to overwrite a task instead of appending to what's already there.

When you no longer want the existing behavior the overwrite method can come in handy.

require 'rubygems'
require 'rake'

class Rake::Task
def overwrite(&block)
@actions.clear
enhance(&block)
end
end

task :the_task do
p "one"
end

Rake::Task[:the_task].overwrite do
p "two"
end


Rake::Task[:the_task].invoke
# >> "two"

The overwrite method is good, but sometimes you want to redefine the task using one of the specialized Rake tasks. I recently wanted to redefine the test task, so I created the abandon method to remove the existing definition.

require 'rubygems'
require 'rake'
require 'rake/testtask'

class Rake::Task
def abandon
@actions.clear
end
end

task :the_task do
p "one"
end

Rake::Task[:the_task].abandon

Rake::TestTask.new(:the_task) do |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end

Rake::Task[:the_task].invoke
# >> Expectations ..................
# >> Finished in 0.00442 seconds
# >>
# >> Success: 18 fulfilled

Hopefully you wont need this type of thing very often, but it can be handy when you want to overwrite a task that has been previously by a framework you've included.

Update below...
Ola Bini pointed out that I'm not clearing the prerequisites. Clearing the prerequisites is something you can do without any modifications to rake.

Rake::Task[:task_name].prerequisites.clear

Also, if you want prerequisites cleared as part of overwrite or abandon, you can easily add it to both tasks.

class Rake::Task
def overwrite(&block)
@actions.clear
prerequisites.clear
enhance(&block)
end
def abandon
prerequisites.clear
@actions.clear
end
end