Ruby 仅当不是nil时分配变量

Ruby 仅当不是nil时分配变量,ruby,null,variable-assignment,Ruby,Null,Variable Assignment,我每页都有@obj.items\u,开始时是20,我希望下面的方法仅当多个项目不是nil时才为其赋值: def fetch_it_baby (many_items = nil) @obj.items_per_page = many_items 使用上述代码,即使many_items为nil,每页@obj.items仍保持20。为什么?这是“好”的编码吗?我不应该用像这样的东西吗 @obj.items_per_page = many_items || @obj.items_per_pag

我每页都有
@obj.items\u
,开始时是
20
,我希望下面的方法仅当
多个项目
不是
nil
时才为其赋值:

def fetch_it_baby (many_items = nil)
    @obj.items_per_page = many_items
使用上述代码,即使
many_items
nil
,每页
@obj.items仍保持
20
。为什么?这是“好”的编码吗?我不应该用像这样的东西吗

@obj.items_per_page = many_items || @obj.items_per_page

还是有第三条路?无论哪种方式,我都觉得不太舒服。

我通常看到的风格是这样的:

@obj.items_per_page = many_items if many_items
这将使用内联条件,同时避免使用负数或双负数条件

即使多个项目为零,每个页面的@obj.items仍然为20

这听起来像是无论什么类
@obj
都有一个自定义修饰符方法
items\u per\u page=
,只有在新值不是
nil
时才更新该值。这不是标准的Ruby。例如,根据这一定义:

class Demo
  attr_accessor :items_per_page
end
我有这样的行为:

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

我建议如下,因为它清楚地表明,如果调用方未在调用中指定
多个\u项
,则您有一个默认赋值:

def function(argument = nil)
  variable = argument || 20
  ...
end
但是,由于您指定仅当值不是
nil
时才进行赋值,因此需要检查
nil
值,否则如果值为
false
,您将错过赋值。如果您真的需要这种情况,那么解决方案就更冗长了:

def function(argument = nil)
  variable = argument.nil? ? 20 : argument
  ...
end

您可以使用
&&=
(与
| |=
仅在nil或false时用于赋值的方式相同)

的答案是我的答案,但另一个“第三种方法”是使用:


我正在使用Rails,我也有类似的需求

您可以在模型上定义方法:

class Gift < ApplicationRecord
  def safe_set(attribute, value)
    return if value.nil?
    send("#{attribute}=", value)
  end
end

对于Rails,您还可以使用所述的
presence


我们在rails中还有一个方法可以帮助删除为零的值

紧凑的

此方法可与数组hash一起使用。返回相同的数据,删除所有为零的值

例如:

紧凑型数组

进一步参考:


foobar&&=3
在此处返回
nil
。这可能自2015年以来有所改变吗?不,它的行为与预期一样,如
foobar=foobar&&3
。问题是,我回答的是“仅当变量不为零时分配变量”,而问题暗示了“仅当值不为零时分配变量”。有没有更优雅的方式来表达同样的意思?像一些疯狂的归因标志?如果每个页面有
@obj.items\u这样的内容,如果=多个项目
> a = 20    # => 20 
> a &&= 30  # => 30
> a         # => 30
> a = nil   # => nil
> a &&= 30  # => nil
> a = false # => false
> a &&= 30  # => false
> a = {}    # => {}
> a &&= 30  # => 30
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
class Gift < ApplicationRecord
  def safe_set(attribute, value)
    return if value.nil?
    send("#{attribute}=", value)
  end
end
g = Gift.new
g.colour = 'red'
g.safe_set(:colour, nil)
g.colour  -> 'red'
g.safe_set(:colour, 'green')
g.colour  -> 'green'
region = params[:state].presence || params[:country].presence || 'US'