我有一个数据对象,其中包含用于各种输入的数十个 attr_accessor 字段。我可以以某种方式定义类,以便所有字段的所有设置器将例如将值设置为空字符串而不是尝试的 nil?
问问题
168 次
2 回答
9
这是一个小模块:
module NilToBlankAttrAccessor
def nil_to_blank_attr_accessor(attr)
attr_reader attr
define_method "#{attr}=" do |value|
value = '' if value.nil?
instance_variable_set "@#{attr}", value
end
end
end
只需将其混合:
class Foo
extend NilToBlankAttrAccessor
nil_to_blank_attr_accessor :bar
end
并使用它:
foo = Foo.new
foo.bar = nil
p foo.bar # => ""
foo.bar = 'abc'
p foo.bar # => "abc"
这个怎么运作
NilToBlankAttrAccessor#nil_to_blank_attr_accessor
首先通常定义attr_reader:
attr_reader attr
然后它通过定义一个与访问器同名的方法来定义编写器,只是在末尾带有一个“=”。所以,对于属性:bar
,方法被命名为bar=
define_method "#{attr}=" do |value|
...
end
现在它需要设置变量。首先它将 nil 变成一个空字符串:
value = '' if value.nil?
然后使用 instance_variable_set,它执行实例变量赋值,其中实例变量在运行时才知道。
instance_variable_set "@#{attr}", value
Foo 类需要 nil_to_blank_attr_accessor 是类方法,而不是实例方法,因此它使用extend
而不是include
:
class Foo
extend NilToBlankAttrAccessor
...
end
于 2013-03-16T16:26:13.303 回答
1
而不是做
object.foo = given_input
你应该做
object.foo = given_input.nil? ? "" : given_input
或者如果你也想变成false
,""
那么
object.foo = given_input || ""
于 2013-03-16T16:25:43.187 回答