Consider the implementation of
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.
The definition of resolve is pretty straight forward
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 :
Now, when we use objects of this class,
its ok, since we override the :+ method to first resolve before doing the actual concatenation.
The problem arises when we do this,
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.
And there is!
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,
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 :
or put in other words :
[[ The images above are all snapshots taken from his talk.]]
Happy Hacking :)