ruby是一种在分配属性时减少类似代码的优雅方法

ruby是一种在分配属性时减少类似代码的优雅方法,ruby,variable-assignment,Ruby,Variable Assignment,我想给一个人的名字分配许多属性,如果属性为空,那么更新它,但是如果属性已经有值,那么跳过它。代码如下所示: 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

我想给一个人的名字分配许多属性,如果属性为空,那么更新它,但是如果属性已经有值,那么跳过它。代码如下所示:

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

有什么优雅的方法可以避免重复代码吗?

这就是我要做的

%w[ first middle last title suffix ].each do |a|
  send("#{a}=", send("#{a}_parsed")) unless send(a)
end
["first", "middle", "last", "title", "suffix"].map do |method|
  self.send("#{method}=", send("#{method}_parsed")) unless self.send(method) 
end

这就是我要做的

["first", "middle", "last", "title", "suffix"].map do |method|
  self.send("#{method}=", send("#{method}_parsed")) unless self.send(method) 
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"
要测试的简短代码:

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"

实例变量集
在这里有帮助:

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

我尽量避免在调用方法时发送
s,而不管它的作用域状态如何(私有-公共保护)。

实例变量集
可以帮助:

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

我尽量避免在调用方法时发送
s,而不管其作用域状态如何(私有-公共保护)。

通常,在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">
some\u class\u instance=SomeClass.new('foo','bar'))
某类实例
# => #
某个\u类\u实例.update(
*%w[
纽约大学优先
新中东
纽约大学
新书名
新后缀
]
)
某类实例
# => #
我更喜欢使用某种可视化映射,这就是为什么存在符号到变量的散列。使用字符串解析可以更动态地实现这一点,但当算法的某些部分出错时,这可能会导致维护问题,而唯一可以判断的方法是在循环中打印。使用这样的表可以很容易地搜索特定的kev/值关系


问题是,当我们生成动态执行此操作的代码时,我们可能已经编写了一个简单的基于
| |=
的块,然后继续。调试时间会减少,影响什么的因素会非常明显,所有这些都会提高可维护性。所以,从长远来看,我不确定更具活力是否真的能买到任何有用的东西。这是我们在编写代码时经常做的权衡之一。

通常,在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">
some\u class\u instance=SomeClass.new('foo','bar'))
某类实例
# => #
某个\u类\u实例.update(
*%w[
纽约大学优先
新中东
纽约大学
新书名
新后缀
]
)
某类实例
# => #
我更喜欢使用某种可视化映射,这就是为什么存在符号到变量的散列。使用字符串解析可以更动态地实现这一点,但当算法的某些部分出错时,这可能会导致维护问题,而唯一可以判断的方法是在循环中打印。使用这样的表可以很容易地搜索特定的kev/值关系


问题是,当我们生成动态执行此操作的代码时,我们可能已经编写了一个简单的基于
| |=
的块,然后继续。调试时间会减少,影响什么的因素会非常明显,所有这些都会提高可维护性。所以,从长远来看,我不确定更具活力是否真的能买到任何有用的东西。这是我们在编写代码时经常做的权衡之一。

在这种情况下,您还可以使用:)在这种情况下,您还可以使用:)在示例中,
eval
对传递给send的参数的评估缺乏意义;)在示例中,
eval
对传递给send的参数的求值缺乏意义;)