ruby 仅在非 nil 时才分配变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19114232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Assign variable only if not nil
提问by Juuro
I have @obj.items_per_page, which is 20at the beginning, and I want the method below to assign value to it only if many_itemsis not nil:
我有@obj.items_per_page,这是20在开头,我希望下面的方法仅在many_items不是时才为其赋值nil:
def fetch_it_baby (many_items = nil)
@obj.items_per_page = many_items
With the code above, even if many_itemsis nil, @obj.items_per_pageremains at 20. Why? And is that "good" coding? Shouldn't I use something like
使用上面的代码,即使many_items是nil,@obj.items_per_page仍然是20。为什么?那是“好”的编码吗?我不应该使用类似的东西吗
@obj.items_per_page = many_items || @obj.items_per_page
Or is there a third way? I don't feel completely comfortable with either way.
或者有第三种方式吗?我对这两种方式都不太满意。
回答by New Alexandria
The style I generally see looks like this:
我一般看到的风格是这样的:
@obj.items_per_page = many_items if many_items
This uses the inline conditional, while avoiding negative or double-negative conditions.
这使用内联条件,同时避免否定或双重否定条件。
回答by Don Cruickshank
I suggest the following as it makes it clear that you have a default value for the assignment in case the caller did not specify many_itemsin the call:
我建议以下内容,因为它清楚地表明您有一个默认值,以防调用者在调用中没有指定many_items:
def function(argument = nil)
variable = argument || 20
...
end
However, since you specified that the assignment takes places only if the value is not nilthen you'll need to check for the nilvalue otherwise you will miss the assignment if the value was false. If you reallyneed that case then the solution is more long-winded:
但是,由于您指定仅在值不是时才进行分配,nil因此您需要检查该nil值,否则如果值为 ,您将错过分配false。如果您真的需要这种情况,那么解决方案会比较冗长:
def function(argument = nil)
variable = argument.nil? ? 20 : argument
...
end
回答by user
You can use &&=(in the same way as ||=is used to assign only if nil or false)
您可以使用&&=(与||=仅在 nil 或 false 时用于分配的方式相同)
> a = 20 # => 20
> a &&= 30 # => 30
> a # => 30
> a = nil # => nil
> a &&= 30 # => nil
> a = false # => false
> a &&= 30 # => false
> a = {} # => {}
> a &&= 30 # => 30
回答by Mark Reed
Even if many_items is nil @obj.items_per_page remains at 20
即使 many_items 为零 @obj.items_per_page 仍为 20
That sounds like whatever class @objis has a custom modifier method items_per_page=that only updates the value if the new value is not nil. This is not standard Ruby. For example, given this definition:
这听起来像任何类@obj都有一个自定义修饰符方法items_per_page=,只有在新值不是时才更新值nil。这不是标准的 Ruby。例如,给定这个定义:
class Demo
attr_accessor :items_per_page
end
I get this behavior:
我得到这种行为:
irb(main):005:0> demo = Demo.new #=> #<Demo:0x007fb7b2060240>
irb(main):006:0> demo.items_per_page = 20 #=> 20
irb(main):007:0> demo.items_per_page #=> 20
irb(main):008:0> demo.items_per_page = nil #=> nil
irb(main):009:0> demo.items_per_page #=> nil
As for your example, I would probably write it this way:
至于你的例子,我可能会这样写:
@obj.items_per_page = many_items unless many_items.nil?
回答by Escapeit
new-alexandria's answer is my go-to, but another "third way" would be to use a ternary:
new-alexandria的答案是我的首选,但另一种“第三种方式”是使用三元:
class Demo
attr_accessor :items_per_page
end
many_items = 100
@obj = Demo.new
@obj.items_per_page = 20 #=> 20
@obj.items_per_page = !many_items.nil? ? 30 : nil #=> 30
回答by Zack Xu
I am using Rails and I have a similar need.
我正在使用 Rails,我也有类似的需求。
You can define a method on your model:
您可以在模型上定义一个方法:
class Gift < ApplicationRecord
def safe_set(attribute, value)
return if value.nil?
send("#{attribute}=", value)
end
end
So you can do
所以你可以做
g = Gift.new
g.colour = 'red'
g.safe_set(:colour, nil)
g.colour -> 'red'
g.safe_set(:colour, 'green')
g.colour -> 'green'

