我有一个接受单个对象或对象集合的方法。检测传入的内容是否可枚举的正确方法是什么?我目前正在执行以下操作(可行,但我不确定这是正确的方法):
def foo(bar)
if bar.respond_to? :map
# loop over it
else
# single object
end
end
我有一个接受单个对象或对象集合的方法。检测传入的内容是否可枚举的正确方法是什么?我目前正在执行以下操作(可行,但我不确定这是正确的方法):
def foo(bar)
if bar.respond_to? :map
# loop over it
else
# single object
end
end
我会用is_a?
.
bar.is_a? Enumerable
但是有一个更好的方法来获取单个对象或集合,假设调用者知道他们传入的是哪个对象。使用 splat:
def foo(*args)
args.each do |arg|
…
end
end
然后,您可以将其称为foo(single_arg)
、foo(arg1, arg2)
和foo(*argv)
。
我取决于您的确切需求,但区分单个对象和Enumerable
. 特别是, aHash
是一个Enumerable
,但在大多数情况下,它应该被视为单个对象。
通常最好区分单个对象和类似数组的参数。这就是 Ruby 经常做的事情。最好的方法是检查是否arg.respond_to? :to_ary
. 如果是这样,那么所有方法都Array
应该对您可用,如果不将其视为单个对象。
如果您真的想检查Enumerable
,您可以测试arg.is_a? Enumerable
但考虑 aHash
是 an ,枚举数Enumerable
也是如此(并且调用它们甚至不会给您一个数组!)Lazy
map
如果您的目的是循环遍历它,那么标准方法是确保它是一个数组。你可以无条件地这样做。
def foo(bar)
[*bar] # Loop over it. It is ensured to be an array.
end
一次性处理单件物品或收藏品怎么样?
[*bar].each { |item| puts item }
无论bar
是单个项目还是数组或哈希或其他任何东西,这都将起作用。这可能不是使用哈希的最佳选择,但使用数组时效果很好。
另一种确保某事是 an 的Array
方法是使用Array
“功能(技术上仍然是一种方法):
def foo(bar)
Array(bar).map { |o| … }
end
Array
将数组保留为数组,并将单个元素转换为数组:
Array(["foo"]) # => ["foo"]
Array("foo") # => ["foo"]
Array(nil) # => []