如果分配的值存在,如何在ruby中分配而不检查每个步骤

如果分配的值存在,如何在ruby中分配而不检查每个步骤,ruby,Ruby,不幸的是,我想不出一个写这个问题的好方法,我们有很多代码最终都是这样的: @annotation.note = params[:annotation][:note] if params[:annotation][:note] @annotation.style = params[:annotation][:style] if params[:annotation][:style] 我发现如果最后的参数检查很烦人 那么,有没有一种方法可以更简洁地编写它,这样就可以理解,值只有在存在时才会被复制,

不幸的是,我想不出一个写这个问题的好方法,我们有很多代码最终都是这样的:

@annotation.note = params[:annotation][:note] if params[:annotation][:note]
@annotation.style = params[:annotation][:style] if params[:annotation][:style]
我发现如果最后的参数检查很烦人


那么,有没有一种方法可以更简洁地编写它,这样就可以理解,值只有在存在时才会被复制,而不必在每次结束时都询问明确的if?

您可以轻松地将检查提取到一个方法中,从而使代码更加枯燥。比如说:

def copy obj, prop, params
  val = params[prop]
  obj.send "#{prop}=", val if val
end

ann = params[:annotation]
copy @annotation, :node, ann
copy @annotation, :style, ann

还有另一种方法:

@annotation.note = params[:annotation][:note] || @annotation.note

我承认,您确实重复了
@注释。注意
,但语句长度仍然减少了。

这里是另一种尝试:

@annotation.note = params[:annotation][:note] rescue nil
@如果
参数[:annotation][:note]
不存在,则annotation.note将保持为
nil

您也可以尝试以下操作:

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }
一些测试:

require 'ostruct'

@annotation = OpenStruct.new
params = {:annotation => {:note => 'note', :style => 'style'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct note="note", style="style">

@annotation = OpenStruct.new
params = {:annotation => {:note => nil, :style => 'style'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct style="style">

@annotation = OpenStruct.new
params = {:annotation => {:note => 'note'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct note="note">
需要“ostruct”
@annotation=OpenStruct.new
params={:annotation=>{:note=>'note',:style=>'style'}
params[:annotation]。每个_对{k,v | v&&&@annotation.send(“{k}=”,v)}
p@注释
#
@annotation=OpenStruct.new
params={:annotation=>{:note=>nil,:style=>'style'}
params[:annotation]。每个_对{k,v | v&&&@annotation.send(“{k}=”,v)}
p@注释
#
@annotation=OpenStruct.new
params={:annotation=>{:note=>'note'}
params[:annotation]。每个_对{k,v | v&&&@annotation.send(“{k}=”,v)}
p@注释
#

它是如何减少的
| |
的长度与
的长度完全相同。虽然,您对
| |=
有很好的pararrel。params[:annotation][:note]没有重复。我认为这个问题可以用更一般的方式来问。我现在这样问。我认为干燥当然很重要,但另一个重要的价值是清晰。我在Ruby方面不是很高级,所以我不得不承认这里介绍的各种解决方案对我来说最有意义的是Sergios的,因为如果我尝试用其他语言来做,我会这么做。
require 'ostruct'

@annotation = OpenStruct.new
params = {:annotation => {:note => 'note', :style => 'style'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct note="note", style="style">

@annotation = OpenStruct.new
params = {:annotation => {:note => nil, :style => 'style'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct style="style">

@annotation = OpenStruct.new
params = {:annotation => {:note => 'note'}}

params[:annotation].each_pair {|k,v| v && @annotation.send("#{k}=", v) }

p @annotation
#<OpenStruct note="note">
x = params[:annotation][:note] and @annotation.note = x
x = params[:annotation][:style] and @annotation.style = x