Takeaways from watching advanced ruby class design by jim weirich part 1

The following are my learnings after watching Jim Weirich's talk Advanced class design in Ruby.

Consider the implementation of Rake::FileList
alt

The job of the above class is to fetch File system details for a given path, like list of file names, their extensions etc.
Apart from that most of its operations are similar to that of an array.
So we define the class as

class FileList < Array
...
end

We dont load the file system information until the first time the object is being used. Do this with the @resolved flag.
alt

The definition of resolve is pretty straight forward
alt

The problem now is we need to call resolve method before doing any operation with the object!

Or a better solution would be to override :+, :[], :size, :empty? methods, like this :
alt

Now, when we use objects of this class,

alt

its ok, since we override the :+ method to first resolve before doing the actual concatenation.

The problem arises when we do this,
alt

What's happening here : ["main.rb"] is an array object, on which the concatenate message has been passed. The argument is an array(since it inherits from Array class), so it just uses the content of f1, which at this point is empty (as it has not been resolved yet).
This leads to a wrong result.

alt

And there is! to_ary

When to_ary is defined on an object, its telling Ruby, before you do any Array operations with me, call this method on me. This method has to always return an array.

So now we can remove the inheritance from Array class,
alt

and define a to_ary method in the class:

def to_ary
  resolve unless @resolved
  @items
end

So the key learning from this example he gave, is :

alt

or put in other words :
alt

[[ The images above are all snapshots taken from his talk.]]

Happy Hacking :)

Murtuza Kutub

Read more posts by this author.

Chennai, India

Subscribe to Murtuza's Blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!