Mark Needham

Thoughts on Software Development

Ruby: Accessing fields

with 2 comments

I’ve spent a little time browsing through some of the libraries used by my project and one thing which I noticed in ActiveSupport is that fields don’t seem to be accessed directly but rather are accessed through a method which effectively encapsulates them inside the object.

For example the following function is defined in ‘inheritable_attributes.rb’

  def write_inheritable_attribute(key, value)
    if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
      @inheritable_attributes = {}
    end
    inheritable_attributes[key] = value
  end
  def inheritable_attributes
    @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
  end
EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)

If we were using C# we’d have instantiated ‘@inheritable_attributes’ at the field definition with ‘EMPTY_INHERITABLE_ATTRIBUTES’ like so…

public class SomeClass {
	private Dictionary<string, object> inheritableAttributes = new Dictionary<string, object>();
}

…but we can’t do that in Ruby because we don’t need to explicitly define all our fields, we just start using them.

I’m assuming this is quite a common pattern in Ruby and in a way it’s quite neat because it restricts the number of direct field references which will make it easier to change the underlying implementation. Kerievsky’s narrowed change refactoring suddenly becomes less necessary!

For that reason I wonder whether it would be a useful pattern in C#/Java or if it would be overkill.

Written by Mark Needham

August 22nd, 2010 at 6:26 pm

Posted in Ruby

Tagged with

  • http://alicebobandmallory.com/ Jonas Elfström

    I’m all for encapsulation but now I’ve read that code a couple of times and I fail to see why is it frozen if the write_inheritable_attribute “unfreezes” it anyway? I also fear it could be hiding that you are in fact working with an instance variable and not a local one. I’m clearly missing the point here.

    “# Prevent this constant from being created multiple times
    EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze” – http://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb – ok, that could be it.

    inheritable_attributes.rb also says: “It is recommended to use class_attribute over methods defined in this file.”

  • http://olabini.com/blog Ola Bini

    Inheritable attributes in ActiveSupport is generally not used for objects, but for classes. The reason has nothing to do with encapsulating fields, but instead has to do with allowing objects to inherit attributes if they don’t have their own values. This is used on a class level in ActiveRecord among other things.