As with everyone, it seems, some more twiddling and playing with this
yielded me a better, faster, and smaller solution.
This also beats my prior solution in that a? returns only true or false,
and variables are kept with the object rather than in a hash with the
object as a key. The reader methods also won't take an argument now.
(They did before.)
9 lines with a little golfing: (8 if you ditch the line for multiple
definitions, which isn't needed for passing the koans).
It's pretty much the same as most of the other solutions out there, now.
def attribute(arg,*rest,&b)
attribute(*rest,&b) if rest.any? # Allow multiple definitions.
n = (arg.is_a?(Hash) ? arg.keys[0] : arg).to_s
b ||= lambda { arg.is_a?(Hash) ? arg[n] : nil }
attr_writer n
define_method(n) { instance_variables.include?('@'+n) ? \
instance_variable_get('@'+n) : instance_eval(&b) }
define_method(n+'?') { ! [nil,false].include?(send(n)) }
end
Blast it, Ara, how do I stop myself from doing more and more tweaking? ;)
- Greg