Greg Millam
2/19/2006 7:56:00 PM
Here's my solution: Took me about 15 minutes to solve the koans. I agree
with everyone else: Great quiz =). Continuous fiddling with it made me
late for a date, and when I tried explaining why, she just stared at me.
"Meta cones? What's that?" Ah well!
My koan solution, 9 lines:
def one_attribute(arg,&b)
name = (arg.is_a?(Hash) ? arg.keys[0] : arg).to_s
p = Hash.new( arg.is_a?(Hash) ? arg[name] : nil )
fun = lambda { |*args|
p[self] = *args unless args.empty?
(p.include?(self) or !b) ? p[self] : instance_eval(&b)
}
['','?','='].each { |ch| define_method(name+ch,&fun) }
end
And to make it accept multiple arguments to work with the benchmark
suites (10 lines):
def attribute(arg,&b)
attribute(*rest,&b) if rest.any?
name = (arg.is_a?(Hash) ? arg.keys[0] : arg).to_s
p = Hash.new( arg.is_a?(Hash) ? arg[name] : nil )
fun = lambda { |*args|
p[self] = *args unless args.empty?
(p.include?(self) or !b) ? p[self] : instance_eval(&b)
}
['','?','='].each { |ch| define_method(name+ch,&fun) }
end
With comments:
def attribute(arg,&b)
# Allow multiple attributes to be set and defined.
attribute(*rest,&b) if rest.any?
# The name of the attribute.
name = (arg.is_a?(Hash) ? arg.keys[0] : arg).to_s
# p holds all the attributes for each object.
# This is wasteful since in real use, this would cause
# Each object that's set an attribute to be kept in
# memory.
p = Hash.new( arg.is_a?(Hash) ? arg[name] : nil )
# The only method I define: It takes 1 or more arguments.
# If it's given an argument, it assigns. In all cases,
# It returns.
fun = lambda { |*args|
# Assign if necessary.
p[self] = *args unless args.empty?
# If it's been assigned, or there's no block, return
# Its saved value (Or Hash's default)
(p.include?(self) or !b) ? p[self] : instance_eval(&b)
}
# Assign that method to all 3 methods we need.
['','?','='].each { |ch| define_method(name+ch,&fun) }
end
More quizzes like this would be much appreciated. It rocked.
Ara++
- Greg