Recently, I've found myself writing and rewriting class attribute accessors, like
class Foo
def self.bar
@@bar
end
def self.bar=(bar)
@@bar = bar
end
end
Being from the old school, while I'm not adverse to just using the @@ directly inside the class, I prefer some encapsulation. And when you want to expose the class' innards, you need to write these methods anyway. This if fine, but it gets a bit too verbose for me.Instance attributes are exposed easily with the attr methods
class Mumble
attr_accessor :barfle
end
which creates the barfle and barfle= instance methods. What I want is an analogousclass Foo
class_attr_accessor :bar
end
to create my self.bar and self.bar= methods. Metaprogramming to the rescue!class Module
def class_attr_reader(*kattrs)
kattrs.each { |kattr|
ka = kattr.to_s
reader = <<EOS
def #{ka}
@@ka
end
EOS
self.module_eval reader
}
end
def class_attr_writer(*kattrs)
kattrs.each { |kattr|
ka = kattr.to_s
writer = <<EOS
def self.#{ka}=(#{ka})
@@#{ka} = #{ka}
end
EOS
self.module_eval writer
}
end
def class_attr_accessor(*kattrs)
class_attr_reader(*kattrs)
class_attr_writer(*kattrs)
end
end
Sweetness. I just love Ruby!
No comments:
Post a Comment