Whether or not you agree with the use of lazy initialized attributes, you’d probably agree that writing the accessor method can be a bit tedious at times; especially if you’re used to Ruby’s attr_accessor, attr_reader, and attr_writer methods.
This Hacktastic entry introduces a couple nice (at least fun to write) little Ruby class methods (based on Jay Fields’ blog entry, “Ruby: Lazy Initialized Attributes“) to assist with lazy initialized attribute declarations.
Let’s take a quick look at how one might use lazy_attr_accessor & lazy_attr_reader
class Foo lazy_attr_accessor :bar => [], :woot => :bam end foo = Foo.new puts "Before = #{foo.bar.inspect}" # Before = [] foo.bar << 2 puts foo.woot # bam foo.woot = :wooooooooot puts foo.woot # wooooooooot puts "After = #{foo.bar.inspect}" # After = [2]
And the hack in all it’s glory…
class Object def self.lazy_attr_reader(hsh) hsh.each do |method_name, default_value| self.send :define_method, method_name.to_sym do var_name = "@#{method_name}" instance_variable_set(var_name, default_value) unless instance_variable_defined? var_name instance_variable_get var_name end end end # creates both lazy_attr_reader and attr_writer def self.lazy_attr_accessor(hsh) attr_writer *hsh.keys lazy_attr_reader hsh end end
I’m not claiming this is a best practice, or even the best way to do this so feel free to share any suggestions you might have.
Enjoy!