Displaying articles with tag

If it quacks like a duck...

Posted by andy, Wed Feb 20 09:00:00 UTC 2008

If it quacks like a duck...

duck-typing is the Way of Ruby and Rails programming. The phrase attributed to James Whitcomb Riley refers to the preference in Ruby and Rails to be concerned with what an object does (methods and attributes) rather than what an object is (it's class). That makes a lot of sense from a modeling perspective. We create classes as representations of like things, but we really deal with them in terms of the way we get to the distinguishing attributes and the kinds of things that it can do because it is a member of that group.

It makes even more sense from a Rails perspective. One of the great mantras of Rails programming is the DRY principle: Don't Repeat Yourself. A primary means of not repeating yourself is to capture reusable functionality in modules and mix those modules into the classes that need to be able to do those kinds of things. Modules are, first and foremost, abstractly written collections of methods... ways of describing how a duck quacks...

Duck typing is more than just an interface implementation. In most static languages the emphasis is on grabbing a particular interface on an object and then making use of that interface as a contract for interaction. With duck typing you really could not care less whether or not you have an interface. You really only care about whether or not the duck can quack. So you ask it:

duck.respond_to?(:quack)

How I learned to love ducks

Okay, so all the duck typing talk may be old hat to you by now. No matter. It was old hat to me, too. I just forgot to do it. Call it old habits dying hard but my code was littered with type-checking.

A particularly bad area of my largest application is designed to allow the end user to set up their own business processes. The code is full of subclasses that each perform one business function and the user hooks them up to design their larger processes. Where it begins to suffer is from the "all roads lead to Rome" problem. For our customers there is a central object with which they deal, but different users will typically get a handle on it through a different association. Rather than force the user to navigate up the object graph we decided to let the process step do the navigation for them. Falling back on old habits I'd have code looking like this

def apply(target_object, attributes={})
  case
    when target_object.is_a?(Widget)
      return target_object.foo.bar! attributes
    when target_object.is_a?(Cog)
      return target_object.foo.bar! attributes
    when target_object.is_a?(Foo)
      return target_object.bar! attributes
  end
  raise(ArgumentError, "No, foo on you!") 
end

The basic idea is to call the bar! method on a Foo class object, but allow the user to apply the process in any context that knows how to navigate up to the Foo class object (including a Foo instance itself). Obviously the repetition was screaming for some refactoring. Enter duck typing.

def apply(target_object,  attributes)
  foo = target_object.respond_to?(:foo) ? target_object.foo : target_object
  raise(ArgumentError, "Duck foo on you") unless foo.respond_to?("bar!")
  foo.bar! attributes
end

Duck typing brings a lot of advantages to that code. Obviously it eliminates the repetition. An important corollary is that it reduces the code base so there is less to maintain and less to break. Duck typing in this scenario also decouples the method from the classes that might need to use it. This is important in two regards. First, it means that I can eliminate one of those classes like the Widget class and not have to modify all the places that refer to the Widget class to eliminate 'undefined constant' errors. Second, it means that I can now introduce new objects that have a handle on the Foo class and automatically gain the ability to use this process step without modification. A less obvious point is that the code now fails more quickly if it's passed a target object that doesn't know Foo; it does not have to wait until all the branches of the case statement fail.

In my opinion, the nicest part of the duck-typing focused refactoring is that it makes the intentions of the method much clearer. Like a really good joke or a really bad pun, the punch is in the final line. What's the objective? To call 'bar!' with the appropriate attributes on a Foo instance.

0 comments | Filed Under: Ruby | Tags:

Objective fun: Even methods can be objects

Posted by andy, Thu Feb 14 13:00:00 UTC 2008

Even Methods Can Be Objects

One of the great things about Ruby is the extent to which everything is an object. There are significantly fewer 'primitives' in Ruby than in any other language with which I've worked. Even numbers are objects. Even methods are objects. Well, at least they can be.

Say Hello to My Little Friend Proc

Methods, at least code blocks, can become objects through the Proc class. As the second edition of Programming Ruby says it:

Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables.
Huh? Basically, the Proc class lets you wrap up a block of code in an object, call it some place, and when it's called it's aware of the context from which it was called. GoF fans will probably recognize this as a form of the command pattern.

Okay, let's get down to brass tacks. As you'd expect, you create a new Proc instance by calling new. This method accepts a block with an arbitrary number of block parameters. Why an arbitrary number of them? Because those block parameters are going to become the parameters you use when you invoke the method you're wrapping up. Again, let's defer to Programming Ruby and look at their example:

def genTimes(factor)
  return Proc.new {|n| n*factor }
end

times3 = genTimes(3) 

times3.call(12)  ยป 36

So what's going on here... the genTimes method accepts an argument called 'factor' and creates a Proc instance (a wrapped up method) with it. The wrapped up method accepts a single parameter it calls 'n' and returns the result of multiplying n and factor. Since this is a closure, the Proc is aware of the surrounding context and it pulls in 'factor' from genTimes. In the call 'genTimes(3)', factor is assigned the value 3 (duh), so the result of the call is to hand back an object-wrapped method that calculates n * 3.

As the Proc basically implements the command pattern you can use this object by invoking the command -- sending the 'call' message. In the example above the method expects one parameter (n) which is why the next-to-last line says, 'times3.call(12)'... the time3 object has a method that multiplies an argument by 3, and when called with the argument 12 you get 12 * 3 = 36. That's not quite so painful.

So Where's the Fun?

The 'fun' obviously lies in the way you can use the procs. In his brilliant book The Rails Way early adopter Obie Fernandez provides a great example that really struck a chord with me (I won't spoil the ending... buy the book!). At the end of his chapter on helpers Fernandez refactors a very specific partial into a very general custom helper. What struck a chord was that the partial essentially needed a 'description' method for the objects that it rendered. Obviously that was not a problem in the very specific original implementation, but it became one when trying to generalize the code. Enter Proc, stage right.

def cool_helper(collection, opts={})
...
opts[:description] ||= Proc.new{|item| itemd.description}
...
render :partial => 'shared/cool_partial',
  :locals => {:description => opts[:description], ... }
end

In line 3 the refactored helper method creates a default Proc instance to handle the initial need for the description. All the proc does is call the 'description' method on the object that it's passed. The nice thing about this is that the default functionality matches what was being done in the original implementation. More importantly, though, this proc is being created as one of the optional parameters that can be supplied by the caller. That means if you would like to reuse the helper with an object that does not have a 'description' method (accessor or otherwise) then you can supply your own 'description' method to the renderer not in your object. For example, what if you now wanted to use this helper to display a list of sports teams and you wanted the description to be the 'name' attribute?

cool_helper my_teams, :description=>Proc.new{|item| item.name}

And there is where it gets fun. Since the proc is an object you can pass it between other objects, but what you're really passing is the ability to perform some custom functionality. The beauty, of course, is that the partial gets to remain blissfully ignorant of the implementation. It does not know or care whether it's invoking the description or name or any other attribute or method. It simply issues the 'call' method and the wrapped up function handles the rest. Something like this:

<div class="description"><br/>
  <%= description.call(item) %><br/>
</div>

In the snippet above, just remember that 'description' is the name of the local variable passed into the partial through the :locals hash... and that variable is the object-wrapped method (Proc) that calls the description on your item.

0 comments | Filed Under: Ruby | Tags:

Static thinking about a dynamic language

Posted by andy, Tue Feb 05 09:00:00 UTC 2008

Static thinking about a dynamic language

If you've approached Ruby from a background in programming with static (compiled) languages it's easy to get a lot of "static" in your thinking about Ruby. One of the most common places to lose sight of t dynamic nature of the Ruby language is in class definitions. A class definition is really a call to a method in Kernel that creates a global constant with a reference to the object that represents the class, but Ruby has so faithfully repeated the class-definition language of static languages that we forget that we're actually executing code.

Who cares if class definitions are dynamic?

The dynamic nature of class definitions in Ruby can be a big deal if you take advantage of it. Mike Clark points out a nice use of the dynamic nature of Ruby in the forthcoming Advanced Rails Recipes. The basic scenario is that you've got an ActiveRecord model that contains data that is primarily intended to be constant for the life of the application -- something like a table of states and provinces (so Clark) or menu items. Rather than look for performance improvements through caching, you could instead create a constant array on the ActiveRecord class that is populated as the class is created.

class MenuItem < ActiveRecord::Base
  MENUS = { :start_menu=>1, ... }
  START_MENU_ITEMS = find(:all, :order=>"position, name", :conditions=>{:menu_id=>MENUS[:start_menu]})
end

The MenuItem class above has already inherited the class-level find() method from ActiveRecord::Base we we make use of it during the class creation process. By doing this the constant data stays in memory and need not be cached. Of course, care should be taken to make sure that the amount of data stored in this constant array is not so large as to reduce performance elsewhere.

The dynamic nature of Ruby class definitions can also help to keep your class-definitions DRY. I've recently been working on a project in which a Person may have many Addresses. Simple enough. But the Addresses need to be subclassed, using single table inheritance, so that I can distinguish a home address from a work address. Oh, yeah, the Addresses also have a date range associated with them so that we can track when you plan on moving to a new Address, which in turn leads me to a need to know the current home address and work address and ... This could get very messy. But it's not if we take advantage of the dynamic nature of Ruby.

class Address &lt; ActiveRecord::Base
  self.inheritance_column = 'address_type'
  ADDRESS_TYPES = %w(HomeAddress WorkAddress SchoolAddress TemporaryAddress)
  belongs_to  :addressable, :polymorphic=&gt;true
end

Address::ADDRESS_TYPES.each do |address_type| 
  eval "class #{address_type} &lt; Address; end"
end

class Person < ActiveRecord::Base
  has_many  :addresses, :as=&gt;:addressable
  Address.subclass_names.each do |address_type| 
    self.send(:has_one, "current_#{address_type.underscore}", 
                      :as=&gt;:addressable, 
                      :class_name =&gt; address_type,
                      :conditions=&gt;['activated_on &lt;= ? AND deactivated_on IS NULL OR deactivated_on&gt;?', Date.today, Date.today])
  end
end

In the code above I'm actually taking advantage of Ruby's dynamics twice. In lines 7-9 I'm iterating through each of the ADDRESS_TYPES declared in the Address class above and declaring a new subclass for each entry in the array. This may not work in every situation; certainly in most instances of subclassing you'll want to add code to the subclass. It works here, though, because the subclass name will be used in rendering (e.g., putting a nice home or work image next to the address with css).

Lines 14-18 is where I've used the dynamic nature of Ruby class declarations to keep things DRY. The Address.subclass_names method simply iterates over the subclassess of Address and returns an array of the names. This might seem overkill since ADDRESS_TYPES already has this information but it will allow me to know if classes are created in some way other than through the loop in lines 7-9. That said, lines 14-18 simply iterate over all the names of the subclasses and creates an association between person and one member of the addresses collection. Specifically, it creates an Address#current_home_address for the HomeAddress class and so on.

0 comments | Filed Under: Ruby | Tags: