July 16, 2007

ActiveRecord Inference

If you know anything about Rails, you'll know that ActiveRecord allows the attributes of objects to be inferred from their associated table column names. You may be curious about how this happens. As I'll show you, it's due to dynamic features of the Ruby language.

Suppose we have a model class.

class Programmer < ActiveRecord::Base
  has_many :skills

  def full_name
    first_name + " " + last_name
  end 
end

This class is based on the following table:

create table programmers (
  id                  integer       not null,
  first_name          varchar(255)  not null,
  last_name           varchar(255),
  favourite_language  varchar(255),
  primary key (id)
);

Now we can code:

joe = Programmer.new
joe.first_name = "Joe"
joe.last_name = "Bloggs"
joe.favourite_language = "Ruby"
joe.save

So, how does Ruby enable Rails to infer the attribute names?

The answer can be found in a couple of classes within ActiveRecord::Base.

def initialize(attributes = nil)
  @attributes = attributes_from_column_definition
  @new_record = true
  ensure_proper_type
  self.attributes = attributes unless attributes.nil?
  yield self if block_given?
end
def method_missing(method_id, *args, &block)
  method_name = method_id.to_s
  if @attributes.include?(method_name) or
      (md = /\?$/.match(method_name) and
      @attributes.include?(query_method_name = md.pre_match) and
      method_name = query_method_name)
    define_read_methods if self.class.read_methods.empty? && self.class.generate_read_methods
    md ? query_attribute(method_name) : read_attribute(method_name)
  elsif self.class.primary_key.to_s == method_name
    id
  elsif md = self.class.match_attribute_method?(method_name)
    attribute_name, method_type = md.pre_match, md.to_s
    if @attributes.include?(attribute_name)
      __send__("attribute#{method_type}", attribute_name, *args, &block)
    else
      super
    end
  else
    super
  end
end

Looking at these methods we can see that method_missing dynamically generates the setter methods for the Programmer object from the @attributes loaded in initializer.

The method_missing method is one of the fundamental tools within the Ruby metaprogramming kit bag. It allows the programmer to enable classes to respond to arbitrary method calls. It is the key to how ActiveRecord inference works.

I think this is a good example of how the power of Ruby's dynamic features underpins the Rails framework. There are many more waiting to be explored in the source code.

Posted to Rails by Keith Pitty at 2:19 PM Permalink | Comments (0)

July 9, 2007

Relative Health

"Have a look at that bloke in the black shorts", I exclaimed. "That's the definition of guts."

Yesterday was a very chilly day on the golf course. My younger playing partners thought I was referring to how cold the bloke on the other fairway was due to the fact that his black shorts were very short and exposing most of his legs to the elements.

"No", I said. "Have a closer look." I had to point out that in fact the golfer in very short black shorts had an artificial leg. I have to admit that when I first noticed him it gave me a jolt. Recently I've been a little preoccupied with my own health problems, which aren't insignificant but when I saw this bloke it gave me a wake-up call. It was as if he was saying "just get on with it; life is too short to mope around worrying about not being in perfect health." I'm not intending to ignore the need to improve my health. Rather it is a matter of gratitude. I should be grateful that I am in relatively good health. Having two good arms and two good legs is so easy to take for granted.

Actually, seeing this one-legged golfer reminded me of another bloke I knew during my university days. The courage of this particular bloke could not be called into question. He played Australian Rules football with an artificial leg. Now that is gutsy!

Posted to Health, Personal by Keith Pitty at 10:05 PM Permalink | Comments (3)

MacBook Pro!

I'm not writing this to gloat or make any of my fellow developers jealous. Honest! However, a few of my colleagues know that I recently took delivery of a new MacBook Pro to replace my aging iBook and they would expect me to blog about it. So here goes.MacBookPro.jpg

Of course the new machine is a treat to use. I was very pleasantly surprised with the painless migration from my old iBook. During the set-up process, everything within my user context on the iBook was seamlessly transferred across via a firewire cable. To get back to roughly where I was on my old machine I then needed to install Xcode, X11 and follow this excellent guide to setting up a Rails development environment (I did try MacPorts but encountered a problem and gave up.)

Then it was time to install Parallels. I had been looking forward to this with much anticipation. One of my justifications for upgrading to a MacBook Pro with 4GB RAM was to allow me to run Windows XP, which I need for tools such as Rational Software Architect that I currently use to earn a living. So far Parallels is working like a dream. I have a 1.5GB virtual machine for Windows XP and love the Coherence view mode that allows me to use a Windows program within an OS X window. One day soon I hope to create another VM for Ubuntu. For now I want to focus on making the most of this MacBook Pro to be productive in OS X or Windows wherever I am.

So there you have it. After three days with my second Apple laptop I'm definitely giving it the thumbs up!

Posted to Computers by Keith Pitty at 9:48 PM Permalink | Comments (1)

July 4, 2007

Java EE 6: Don't Hold Your Breath

Yesterday the Java EE 6 proposal was published. Rod Johnson, founder of the Spring Framework, thinks it's a step in the right direction (via InfoQ). I agree that it is a refreshing change in thinking.

As Rod also notes, Java EE has been challenged by Ruby on Rails. Reports from the recent Rails conference in Portland, Oregon have indicated that a significant proportion of attendees were from "enterprise" organisations. ThoughtWorks is using Ruby for 40% of new business this year in the US. Here in Australia there is a vibrant and growing Rails community.

I support Sun for taking steps to reduce the bloat in Java EE and to be more inclusive of open source innovation. But will Java EE 6 be delivered and supported soon enough? If the specification is finalised according to the proposed schedule (Q4, 2008) we can expect vendors to support Java EE 6 in 2009 at the earliest. Meanwhile most users are still stuck on J2EE 1.4 because they are waiting for their vendor to catch up to Java EE 5.

Thank goodness for open source. I'll be focussing on Rails and Spring rather than holding my breath waiting for Java EE 6.

Posted to Java, Rails by Keith Pitty at 9:08 PM Permalink | Comments (1)

July 3, 2007

API Documentation at Your Fingertips

Thanks to a tip from Jon Tirsen I've just discovered gotAPI, a wonderful site that enables the developer to quickly find documentation for a wide range of APIs.

Of course it won't help me when I'm offline but maybe Google Gears will fix that?

Posted to Software Development by Keith Pitty at 10:36 AM Permalink | Comments (1)

July 2, 2007

On Meditation

Why meditate?

If it helps to improve your health and general well-being, why not? I think meditation is one of those activities that works for some people and not for others. I've tried various techniques over the years but found the following, courtesy of Pat Davies, most useful:

  1. Close your eyes and in time with your breath silently say the word relax three times.
  2. In time with your breath, count up to 10 and then back to one.
  3. Starting at your feet or head, work your way up or down your body tensing it and then allowing it to relax on the out breath.
  4. Imagine a tension dial showing how tense you feel on a scale from 1 to 10. As you breathe, imagine the dial changing to show a reduced amount of tension.
  5. Check how your body feels.
  6. Imagine being in a favourite, peaceful outdoor place. It's a special place that you can draw comfort from. Spend a while there.
  7. When you're ready, start to become aware of the sounds immediately around you. Then allow yourself to become aware of sounds further away. If you are indoors, these sounds may come from outside.
  8. Finish your meditation by silently and confidently saying to yourself: I'm calm, I'll manage, I'm in control.

Having shared that, my new year's resolution (well, it's a new financial year, isn't it?) is to meditate every day.

Posted to Health, Personal by Keith Pitty at 2:02 PM Permalink | Comments (3)