以下的是我自己写的版本
module CheckedAttributes
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def attr_checked(attr_name, &validation)
define_method("#{attr_name}=") do |value|
result = validation.call value
if result
@attr_name = value
else
raise "value is not valid"
end
end
attr_reader attr_name.to_sym
end
end
end
以下是书中的版本
module CheckedAttributes
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def attr_checked(attribute, &validation)
define_method("#{attribute}=") do |value|
raise 'Invalid attribute' unless validation.call(value)
instance_variable_set("@#{attribute}", value)
end
define_method attribute do
instance_variable_get "@#{attribute}"
end
end
end
end
测试代码
class Person
include CheckedAttributes
attr_checked :age do |v|
v >= 18
end
end
me = Person.new
p me.age = 39 # OK
p me.age = 39 # OK
p me.age = 12 # not OK