# Deja vu all over again

Written by Piers Cawley on

Back when I was still programming Perl, one of the common mistakes that you’d see when people wrote lazily initialized object accessors was code like:

 
sub get\_content {
my($self) = @\_;$self->{content} ||= 'default content';
}


Code written like this would trundle along quite happily, until you had an attribute where, say, the empty string or 0 were legal values for the attribute. The problems were especially painful when the default value wasn't something that perl treated as false. The correct way of writing that code would be:



sub get\_content {
my($self) = @\_; unless (exists($self->{content})) {
$self->{content} = 'default content' }$self->{content}
}


Which is substantially uglier, but safe.

Safety's important, especially in building block code like accessor methods. An accessor method that works 99.99% of the time is like a compiler that produces correct code 99.99% of the time - useless.

Recently, the usually spot on Jay Fields [wrote up](http://blog.jayfields.com/2007/07/ruby-lazily-initialized-attributes.html) the lazy initialization pattern for Ruby. I'm not entirely sure that I agree with his motivation for the pattern, but I am concerned by his suggested code transformation. He suggests writing your lazy initialization as:



def content
@content ||= 
end


Does that look familiar? This is subject to exactly the same potential bug as the perl code above. Admittedly, the number of possible 'bad' values is reduced to nil and false, but it only takes one. Here's the fix:



def content
unless instance\_variable\_defined? :content
content = 
end
return @content
end


This code is guaranteed to work in all circumstances.

### Going a little bit further...

As Mark Jason Dominus has argued persuasively elsewhere, [patterns are a sign of weakness in a programming language](http://blog.plover.com/prog/design-patterns.html), so how can we go about incorporating this boilerplate code into our language[1].

How about something like this (as yet untested):



class Module
class << self
unless block\_given?
end
unless args.size == 1
raise ArgumentError, "Expected 1 argument"
end
var\_name = "@\#{args.first.to\_s}"
self.define\_method(args.first) do
unless instance\_variable\_defined?(var\_name)
self.set\_instance\_variable(var\_name, default\_block.call(self))
end
return self.send(args.first)
end
end
end
end


This code is a little more complex than the boilerplate code. When the generated method is called, possibly initializing the attribute, the (class << self; self; end).attr_reader_without_default_block(args.first) part replaces the instance's accessor with the default attr_reader implementation and calls that instead. This is arguably premature optimization, but it's not all that evil...

Assuming I've not screwed anything up, that should allow you to write.:



class Article

and have your content lazily initialized. Extending this to let attr_writer take a block too is a reasonably obvious next step.