Update → Rick Olson pointed out the overhead in accessing instance_values, and suggested instead using instance_variable_get.
Done!
Ruby’s attr_accessor is incredibly handy for wiring up your class’s banal getters and setters. If you’re wiring up some simple booleans this way though, wouldn’t you like to get the beauty of Ruby’s method punctuation?
I mean come on, we’re asking a question here.
The old way:
class Doyen attr_accessor :recondite def recondite? self.recondite end end
Blah… Let’s tidy that up.
class Doyen bool_attr_accessor :recondite end
Now our Doyen no longer has doyen.recondite, but simply doyen.recondite? and no visual clutter.
The implementation is simple:
class Module def bool_attr_accessor *args args.each do |arg| self.instance_eval do define_method("#{arg}=") do |value| instance_variable_set("@#{arg}", !!value) end define_method("#{arg}?") do instance_variable_get("@#{arg}") end end end end end
Originally I used an attr_writer *args to simplify the setters, but I decided that since this function would always return a boolean, it would be better to do the conversion on the setter and let the getter simply return the pre-converted value.
I don’t know if you’ve looked at the implementation of #instance_values, but it’s creating a hash of every ivar on each access. That’s not very efficient, and it’s going to leave a lot of clutter for the GC. I think it’s best to keep it simple like instance_variable_get(”@#{arg}”).
February 8th, 2008
Assuming the attribute is supposed to be purely boolean, wouldn’t you be better served by adding
:recondite?,:set_recondite, and, possibly, .I tend to think of boolean accessors as code smells though…
February 11th, 2008
Hmm… note to self: Check the preview!
February 11th, 2008
Boolean accessors certainly aren’t something you need every day, and using descriptive setters like that isn’t a bad idea.
The reason I created these was for simple dirtiness checking on an attribute.
Strictly for convenience.
February 11th, 2008
You can blame James Britt for personally shooting down the proposal to have “attr_accessor :recondite?” fail to DWIM, so you have to write it out long hand.
Piers, you must be effing kidding me.
Dan
May 10th, 2008