RoRLearn.com Home News Articles Tutorials Resources Books Forums
 

Home>Articles>

Object Construction and Blocks

Say you have a class with methods used to set its state. You want to be able to provide state information when constructing a new object, and also to provide amend it subsequently.

Start off with a class and with some methods for setting internal attributes:

  class Person
    def setAge(age) ...
    def setSex(sex) ...
    def setHeight(height) ..
  end

Now, the conventional way of creating and initializing an object of type Person would be to:
  • Provide a constructor with lots of parameters; or
  • Have a null constructor, then call the methods on the returned object.
The first approach is tacky, and can quickly get out of hand as more state is added to an object. We've all seen classes with 10-parameter constructors! However, the second way is also problematic. After calling the constructor, you have to remember to write calls to the various state-setting methods, and you must ensure that no other thread attempts to use the object until the last method has been called.

A Ruby Solution

In Ruby, however, there's a third way:

  $fred = Person.new {
     setAge    34
     setSex    "Male"
     setHeight 71
  }

What we've done is added a block to the call to the constructor. Ruby says "fine", and passes the block in to the initialize method. This is where Ruby lets us be clever. The block that's passed in has 'self' set to whatever was current at the time the constructor was called. That environment probably does not have methods 'setAge' etc. Even if it did, they would not affect the state of the newly constructed Person object. We need to change the value of 'self' to be that of that object before calling the block. And of course, Ruby has a way:

  class Person
    def setAge(age) ...
    def setSex(sex) ...
    def setHeight(height) ...

    def initialize(&block)
        instance_eval(&block);
    end
  end

The call to 'instance_eval' evaluates the block in the context of this object instance, so the calls to setHeight etc all refer to this newly created instance. The object reference is not returned until after the state-setting methods have been called.

Cool, eh?






 
Site Copyright © 2006-2007 RoRLearn.com All rights reserved. Privacy Policy | About Us | Contact Us | Site Map