13

我有@obj.items_per_page,这是一开始的,我希望下面的方法仅在不是20时才为其赋值:many_itemsnil

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

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

4

8 回答 8

21

我一般看到的风格是这样的:

@obj.items_per_page = many_items if many_items

这使用了内联条件,同时避免了否定或双重否定条件。

于 2013-10-01T10:53:51.650 回答
13

我建议以下内容,因为它清楚地表明您有一个默认值,以防调用者在调用中未指定many_items

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

但是,由于您指定仅当值不是时才进行分配,所以您nil需要检查该nil值,否则如果值为 ,您将错过分配false。如果您真的需要这种情况,那么解决方案会更加冗长:

def function(argument = nil)
  variable = argument.nil? ? 20 : argument
  ...
end
于 2013-10-01T10:59:33.990 回答
12

您可以使用(与用于仅在 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
于 2015-07-24T21:34:57.067 回答
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?
于 2013-10-01T10:59:23.123 回答
4

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

region = params[:state].presence || params[:country].presence || 'US'
于 2019-12-12T12:06:03.503 回答
0

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
于 2017-02-09T23:50:42.427 回答
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'
于 2019-07-04T14:53:36.970 回答
0

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

袖珍的

此方法可以与数组、哈希一起使用。返回相同的数据,删除所有为 nil 的值

例如:

array.compact

进一步参考:

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

于 2021-05-19T05:54:54.047 回答