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.
becomes
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
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.
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.
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.
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.
@subject = subject
end
@subject.send sym, *args, &block
end
endbecomes
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
endMotivation
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
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.
@subject = subject
end
@subject.send sym, *args, &block
end
endThis 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.
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
endUsing 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.
attr_accessor :name, :age
empty?(sym.to_s.sub(/^empty_/,"").chomp("?"))
end
self.send(sym).nil?
end
endThe 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.
attr_accessor *args
args.each do |attribute|
define_method "empty_?" do
self.send(attribute).nil?
end
end
end
attrs_with_empty_methods :name, :age
endLabels: define_method, metaprogramming, method_missing, refactoring, ruby
Monday, February 25, 2008
Ruby: Dynamically Define Method
Defining Methods Dynamically
You have methods that can be defined more concisely if defined dynamically.
becomes
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
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.
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.
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.
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.
becomes
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.
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.
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.
With the above code in place, it's possible to define the PostData class like the example below.
You have methods that can be defined more concisely if defined dynamically.
self.state = :failure
end
self.state = :error
endbecomes
def_each :failure, :error do |method_name|
self.state = method_name
endMotivation
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
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.
self.state = :failure
end
self.state = :error
end
self.state = :success
endThe 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
endDynamically 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.
method_names.each do |method_name|
define_method method_name do
instance_exec method_name, &block
end
end
end
endThe instance_exec methodWith def_each now available I can define the methods similar to the example below.
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.
; end
include InstanceExecHelper
begin
old_critical, Thread.critical = Thread.critical, true
n = 0
n += 1 while respond_to?(mname="__instance_exec")
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
def_each :failure, :error, :success do |method_name|
self.state = method_name
endExample: 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.
self.state = :error
end
self.state = :failure
end
self.state = :success
endbecomes
args.each do |arg|
define_method arg do
self.state = arg
end
end
end
states :failure, :error, :success
endExample: 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.
@post_data = post_data
end
post_data[:params]
end
post_data[:session]
end
endWhile 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 << self; self; end).class_eval do
post_data.each_pair do |key, value|
define_method key.to_sym do
value
end
end
end
end
endThe 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.
hash = self
Module.new do
hash.each_pair do |key, value|
define_method key do
value
end
end
end
end
endWith the above code in place, it's possible to define the PostData class like the example below.
self.extend post_data.to_mod
end
endLabels: define_method, metaprogramming, refactoring
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.
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.
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.
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.
Labels: pair programming
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.
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.
We solved this issue by attempting to create the specific presenter and rescuing with the base presenter.
klass = "_presenter".camelize.constantize rescue Presenter
@presenter = klass.newInline 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.
Labels: ruby
Ruby: Creating Anonymous Classes
Classes in Ruby are first-class objects—each is an instance of class Class. -- ruby-doc.orgMost classes are defined using the syntax of the following example.
...
endDefining 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
...
endClass.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.orgThe 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.
# implementation...
true
end
end
klass = Class.new do
include Gateway
end
assert_equal true, klass.new.post(1)
end
endThere 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.
Labels: class, metaprogramming, ruby
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.
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
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
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.
Also, if you want prerequisites cleared as part of overwrite or abandon, you can easily add it to both tasks.
By default Rake Tasks append behavior every time they are defined. The following example shows that both definitions are executed.
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.
@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.
@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.clearAlso, if you want prerequisites cleared as part of overwrite or abandon, you can easily add it to both tasks.
@actions.clear
prerequisites.clear
enhance(&block)
end
prerequisites.clear
@actions.clear
end
endLabels: rake

