Patrick Hurley
2/20/2006 5:11:00 PM
Ok here is my solution:
class Module
def attribute(sym, *more, &blk)
attribute(*more, &blk) unless more.empty?
if sym.is_a?(Hash)
sym.each_pair { |sym, dval| attribute(sym, &(blk || lambda { dval })) }
else
iname = "@#{sym}"
define_method(sym) do
if instance_variables.include?(iname)
instance_variable_get(iname)
else
if blk then instance_eval(&blk) end
end
end
attr_writer(sym)
alias_method("#{sym}?", sym)
end
end
end
A polite and fairly readable, if completely uncommented 19 lines with
support for multiple symbols both in and out of the hash. And here is
the same solution painfully golfed into 4 lines of code -- by the way,
having unit tests are invaluable when golfing, I should have realized
this as golfing is just a deranged form of refactoring, but not being
a golfer this was enlightening :-)
class Module;def attribute(s,*r,&b);attribute(*r,&b) if r.any? ;(Hash===s)?
(s.each {|s,d|attribute(s,&(b||lambda{d}))}):(define_method(s){
instance_variables.include?("@"+s)?instance_variable_get("@"+s):(b&&
instance_eval(&b)||nil)};attr_writer(s);alias_method(s+"?",s));end;end
pth