Hi,
It's 18 lines when you strip comments. The only thing with it is that
the #{sym}? query method doesn't behave exactly right (returning true or
false) but it makes it a bit quicker.
Also I wished for instance_exec to allow the symbol to be passed to the
default block...
Thanks, Ara, for a cool quiz - I had more fun reading the quiz code than
writing my solution :)
class Module
# call-seq:
# attribute :a -> true
# attribute :a, :c => 45, :d => 'stuff' -> true
# attribute(:a) { || default } -> true
# attribute(:a, :b, :c => 4) { || default a, b } -> true
def attribute(*args, &blk)
args.inject({}) { |hsh,arg|
(arg.respond_to?(:to_hash) ? hsh.merge!(arg) : hsh[arg] = nil) ; hsh
}.each { |sym, default|
ivar = :"@#{sym}"
define_method(sym) do
if instance_variables.include? ivar.to_s
instance_variable_get(ivar)
else
instance_variable_set(ivar, default || (instance_eval &blk if blk))
# Ruby 1.9: (instance_exec(sym, &blk) if blk))
end
end
# define_method("#{sym}?") { instance_variable_get(ivar) ? true : false }
alias_method "#{sym}?", sym
attr_writer sym
}.any?
end
end
--
Ross Bamford - rosco / roscopeco.REMOVE.co.uk