I’ve got two.
Here’s the first one I did:
class Module
def attribute( name, &default_block )
name, default_value = name.to_a.first if name.is_a? Hash
default_block ||= proc { default_value }
ivar = "@#{ name }".to_sym
define_method name do
value = instance_variable_get ivar
unless value or instance_variables.include? ivar.to_s
instance_variable_set ivar, instance_eval( &default_block )
else
value
end
end
define_method "#{ name }=" do |value|
instance_variable_set ivar, value
end
alias_method "#{ name }?", name
end
end
23 lines.
Then here’s the second one I did, after Ara clarified that I needn’t use
instance variables:
class Module
def attribute( name, &default_block )
name, default_value = name.to_a.first if name.is_a? Hash
default_block ||= proc { default_value }
name = name.to_sym
define_method( "__default__#{ name }", &default_block )
define_method( :__attributes__ ) do
@__attributes__ ||= Hash.new { |h, k| h[k] = send "__default__#{
k }" }
end
define_method( name ) { __attributes__[name] }
define_method( "#{ name }=" ) { |value| __attributes__[name] =
value }
alias_method “#{ name }?”, name
end
end
18 lines.
Actually, this last one can be mildly golfed down to 13 lines, at the
cost of getting a little ugly and a little slow:
class Module
def attribute( name, &default_block )
name, default_value = name.to_a.first if name.is_a? Hash
default_block ||= proc { default_value }
define_method( “default#{ name }”, &default_block )
define_method( :attributes ) do
@attributes ||= Hash.new { |h, k| h[k] = send “default#{
k }” }
end
define_method( name ) { attributes[name] }
define_method( “#{ name }=” ) { |value| attributes[name] =
value }
alias_method “#{ name }?”, name
end
end
Anyway, that’s all. Both these versions only do one attribute at a
time, since that’s all the tests asked for. Plus I don’t think the
block would make sense for multiple attributes.
And Ara? This Quiz rocked so much. Thank you!
-mental