仅在不是nil时分配变量

时间:2013-10-01 10:47:48

标签: ruby null variable-assignment

我有@obj.items_per_page,开头是20,我希望下面的方法仅在many_items不是nil的情况下为其指定值:

def fetch_it_baby (many_items = nil)
    @obj.items_per_page = many_items

使用上面的代码,即使many_itemsnil@obj.items_per_page仍为20。为什么?这是“好”的编码吗?我不应该使用像

这样的东西
@obj.items_per_page = many_items || @obj.items_per_page

还是有第三种方式?无论哪种方式,我都感到不舒服。

8 个答案:

答案 0 :(得分:10)

  

即使many_items为nil @ obj.items_per_page仍为20

这听起来像任何类@obj都有自定义修饰符方法items_per_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

至于你的例子,我可能会这样写:

@obj.items_per_page = many_items unless many_items.nil?

答案 1 :(得分:9)

我建议以下内容,因为如果调用者未在调用中指定many_items,则表明您具有分配的默认值:

def function(argument = nil)
  variable = argument || 20
  ...
end

但是,由于您指定仅在值不是nil时才进行分配,因此您需要检查nil值,否则如果值为{{},您将错过分配{1}}。如果确实需要这种情况,那么解决方案就更加冗长:

false

答案 2 :(得分:8)

我通常看到的风格如下:

@obj.items_per_page = many_items if many_items

这使用内联条件,同时避免负面或双面负面条件。

答案 3 :(得分:8)

您可以使用&&=(与||=使用的方式相同,仅在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

答案 4 :(得分:0)

new-alexandria的回答是我的回答,但另一种“第三种方式”是使用ternary

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

答案 5 :(得分:0)

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

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

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'

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

<块引用>

紧凑

此方法可用于数组,哈希。返回相同的数据,删除所有为零的值

例如:

<块引用>

array.compact

进一步参考:

https://apidock.com/ruby/v1_9_3_392/Array/compact