Ruby:Object.to_a替代品

我需要将传入的参数(单个对象或集合)转换为Array。 我不知道论证是什么。 如果它已经是一个数组,我想保留它,否则从中创建一个单元素数组。 我想要允许两个method(:objs => obj)method(:objs => [obj1, obj2])

这似乎是最好的方法(Array#to_a返回self):

 arg = arg.to_a 

但ruby文档称Object#to_a很快就会过时 。 有方便的更换吗?

还有比这更简洁的东西吗?

 arg = arg.respond_to?(:to_a) ? arg.to_a : [arg] 

使用方法Kernel#Array :

 Array([1,2,3]) #=> [1, 2, 3] Array(123) #=> [123] 

是的,它起初可能看起来像一个类,但这实际上是一个以大写字母开头的方法。

哇,有人只是暗示了一个非常古老的线索。 :-O但是因为我还没有看到它包含在内,所以我将为完整性添加一条方法:

 arg = [*arg] 

如果它已经是一个数组(因此删除了一个嵌套级别)或创建一个参数数组,这将抛出该参数:

 arg = [1,2,3] [*arg] #=> [1, 2, 3] arg = 1 [*arg] #=> [1] 

似乎只推荐使用Object.to_a ,删除默认的to_a并强制每个类定义自己的(例如, Hash.to_a )。

 self.to_a #=> -:1: warning: default `to_a' will be obsolete "hello".to_a #=> ["hello"] Time.new.to_a #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, "CDT"] h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } h.to_a #=> [["a", 100], ["c", 300], ["d", 400]] 

如果您的参数是Object的实例,请尝试:

 Hash.new(obj).to_a 

@Daniel [对Ollivier的评论]: 重点是我不知道论证是什么。 如果它已经是一个数组,我想保留它,否则创建一个单元素数组。

如果是这种情况,请尝试:

 obj = [obj] if !obj.is_a?(Array) 

如果更适合问题,你可以采取鸭子打字方式,列出你需要的所有方法,并检查对象是否已经拥有它们,如果没有,使它成为一个数组:

 [:[], :each, :etc...].all? { |m| obj.respond_to? m } ? obj : [obj] 

优点是您可以为对象提供机会来实现索引访问的自己的语义。

我不确定这是否有帮助,但我经常需要的不是arg是一个数组,而是arg响应每个。

 arg = [arg] unless arg.respond_to? :each 

我做了很多,总是使用:

 arg = [arg] unless arg.is_a?(Array) 

虽然如果你知道你永远不会将数组作为单独的参数传递,你也可以这样做:

 arg = [arg].flatten 

那么Array.new(1,arg)呢?