我想为一个人的名字分配许多属性,如果该属性为空则更新它,但如果该属性已有值,则跳过它。代码如下所示:
self.first = first_parsed unless self.first
self.middle = middle_parsed unless self.middle
self.last = last_parsed unless self.last
self.title = title_parsed unless self.title
self.suffix = suffix_parsed unless self.suffix
有没有优雅的方法来避免重复代码?
答案 0 :(得分:2)
%w(first middle last title suffix).each do |m|
self.send("#{m}=",eval("#{m}_parsed")) unless self.send(m)
end
要测试的简短代码:
class Foo
attr_accessor :first,:middle
def meth(first_parsed,middle_parsed)
%w(first middle).each do |m|
self.send("#{m}=",eval("#{m}_parsed")) unless self.send(m)
end
end
end
foo = Foo.new
foo.meth(11,'wax')
foo.first # => 11
foo.middle # => "wax"
答案 1 :(得分:1)
%w[ first middle last title suffix ].each do |a|
send("#{a}=", send("#{a}_parsed")) unless send(a)
end
答案 2 :(得分:1)
通常,在Ruby中我们使用以下方法执行此操作:
self.first ||= first_parsed
self.middle ||= middle_parsed
self.last ||= last_parsed
self.title ||= title_parsed
self.suffix ||= suffix_parsed
如果我要更动态地做一点,我会做类似的事情:
class SomeClass
def initialize(first_name=nil, middle_name=nil, last_name=nil, title=nil, suffix=nil)
@first_name, @middle_name, @last_name, @title, @suffix = first_name, middle_name, last_name, title, suffix
end
def update(first_parsed, middle_parsed, last_parsed, title_parsed, suffix_parsed)
{
:first_name => first_parsed,
:middle_name => middle_parsed,
:last_name => last_parsed,
:title => title_parsed,
:suffix => suffix_parsed
}.each{ |k, v|
instance_var = "@#{ k }"
self.instance_variable_set(instance_var, v) unless self.instance_variable_get(instance_var)
}
end
end
使用它:
some_class_instance = SomeClass.new('foo', 'bar')
some_class_instance
# => #<SomeClass:0x007fcb030941a8
# @first_name="foo",
# @last_name=nil,
# @middle_name="bar",
# @suffix=nil,
# @title=nil>
some_class_instance.update(
*%w[
new_first
new_middle
new_last
new_title
new_suffix
]
)
some_class_instance
# => #<SomeClass:0x007fcb030941a8
# @first_name="foo",
# @last_name="new_last",
# @middle_name="bar",
# @suffix="new_suffix",
# @title="new_title">
我更喜欢使用某种可视化映射,这就是为什么符号到变量的散列的原因。使用字符串解析可以更加动态地执行此操作,但是当算法的某些部分出现问题时,这可能会导致维护问题,并且您可以告诉的唯一方法是在循环内打印。使用这样的表可以很容易地搜索特定的kev /值关系。
问题是,当我们生成代码以动态执行此操作时,我们可能已经编写了一个简单的基于||=
的块,并继续前进。调试时间会减少,影响什么的非常明显,所有这些都会提高可维护性。所以,我不确定从长远来看,更有活力的实际购买任何有用的东西。这是我们在编写代码时经常做出的权衡之一。
答案 3 :(得分:0)
这就是我要做的事情
["first", "middle", "last", "title", "suffix"].map do |method|
self.send("#{method}=", send("#{method}_parsed")) unless self.send(method)
end
答案 4 :(得分:0)
instance variable set
可以提供帮助:
class Person
def some_setter_method
%w(first middle last title suffix).each do |attr|
unless instance_variable_get "@#{attr}"
instance_variable_set "@#{attr}", method(#{attr}_parsed).call
end
end
end
end
我试图避免send
,因为它调用方法而不管它的范围状态(私有公共保护)。