Method Aliasing and Aspect-Oriented Programming

One of the things that I have recently played with in Ruby is a sort of aspect-oriented programming. I say “sort of” because Ruby is not really an aspect-oriented language out of the box, but with some inconvenient constructs one can approach problems in this manner, using this mindset. I touched this because I am writing extensions to another program already written in this style. I think a lot of Rubyists do this when modularizing their code. What I saw was that one of the classes I needed to modify was modularized into several components:

class Shape
  module CurvySides
    # ... code supporting curvy sides here ...
  end

  module StraightSides
    # ... code supporting straight sides here ...
  end

  include CurvySides, StraightSides
end

Actually, each concern was in a separate file:

require 'shape/curvy_sides'
require 'shape/straight_sides'

class Shape
  include CurvySides, StraightSides
end

How is that for separation? But wait, you say… what if including each concern requires a change in behavior to the same method? You cannot just define the whole method in both modules; if you ran one the other would not get to assert its behavior.

The solution lies in Ruby’s method aliasing mechanism. Each module defines its own version of the method assuming that there is another, previously defined, version of the method to be called.

class Shape
  def side_length
    0
  end

  module CurvySides
    def self.included (base)
      base.send :alias_method, :side_length_without_curvy_sides, :side_length
      base.send :alias_method, :side_length, :side_length_with_curvy_sides
    end

    def side_length_with_curvy_sides
      side_length_without_curvy_sides + (... other computation ...)
    end
  end

  module StraightSides
    def self.included (base)
      base.send :alias_method, :side_length_without_straight_sides, :side_length
      base.send :alias_method, :side_length, :side_length_with_straight_sides
    end

    def side_length_with_straight_sides
      side_length_without_straight_sides + (... other computation ...)
    end
  end

  include CurvySides, StraightSides
end

So it is not the prettiest code, but it effects the separation of programming concerns a la aspect-oriented programming. For version one of anything I write I will not be using this much, but I think that before someone publishes their work they should consider modularizing it in this way. In fact, this architecture has been a great help to me as I extend the functionality of the class myself. I am simply writing my modifications as modules that are included into the class just like its base functionality. Sometimes they augment existing methods, and I have to make the calls to #alias_method for the class, and sometimes I do not. In any case, it is fun!

  • You can skip to the end and leave a comments. Trackback is currently closed.
  • Trackback URI: http://cosine.org/2007/08/30/method-aliasing-aspect-oriented-programming/trackback/
  • Comments RSS 2.0

Leave a Reply

You must be logged in to post a comment.