接收对象或对象数组、转换它们并添加到现有数组的惯用方式

Phr*_*ogz 1 ruby arrays splat

我有一个方法可以接收单个对象或这些对象的数组。(我从中提取的 YAML 文件有时有foo: bar,有时有一个列表foo: [bar1, bar2]。)

每次调用此方法时,它都应该转换一个或多个值,并将它们添加到内部数组中。

我原来有这个:

class YamlEater
  def initialize
    @foos = []
  end

  def add(o)
    if o.is_a?(Array)
      o.each{ self.add(_1) }
    else
      @foos << FooItem.new(o)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

在我需要在许多不同的方法中使用该模式之后,我将其更改为非递归、更简洁的版本,该版本非常繁重,也许只有高尔夫球手才会喜欢:

  def add(o)
    @foos.push(*[*o].map{ FooItem.new(_1) })
  end
Run Code Online (Sandbox Code Playgroud)

我认为有一种更优雅的方法可以实现相同的目标,并希望有人能分享。

mu *_*ort 5

我可能会使用Kernel#Arrayand Array#concat

def add(o)
  @foos.concat(Array(o).map { FooItem.new(_1) })
end
Run Code Online (Sandbox Code Playgroud)

这可以很好地o.nil?作为奖励。