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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 06:13:18  来源:igfitidea点击:

Assign variable only if not nil

rubynullvariable-assignment

提问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_itemsnil@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'

回答by mcfoton

For Rails you can also use presenceas described here

对于 Rails,您也可以presence按照此处所述使用

region = params[:state].presence || params[:country].presence || 'US'