Ruby .each因单个元素而失败

时间:2017-06-11 02:50:43

标签: arrays ruby iterator

我可以很好地迭代一个数组:

def source_names(packages)
    files = []
    packages.each do |package|
        files << (package + ".ads")
        files << (package + ".adb")
    end
    return files
end

但只要传入一个数组(或者可能是任何集合)。但是,当只有一个包作为更大脚本的一部分传递给此方法时,这会失败,因为类型是字符串,而不是数组中的单个元素:

in source_names&#39;:未定义的方法&#39;每个&#39; for&#34; Generics.Mathematics&#34;:String(NoMethodError)

那么我怎么不关心只传递一个元素,它只被识别为一个字符串?

Clairification :我知道字符串不支持数组方法。我的困惑是为什么我有时会得到一个数组,而是一个字符串来代替单个元素数组。

2 个答案:

答案 0 :(得分:5)

您遇到了该异常,因为类String没有实例方法each

String.instance_methods.include?(:each) #=> false

如果packages是一个字符串,则需要对仅由该字符串组成的数组进行操作。我们可以使用方法Kernel#Array来编写:

Array(packages).each do |package|
如果Array(packages)是一个数组,

packages将返回packages,如果[packages]是单个元素,则返回packages,此处为字符串。

但是,我认为最好将数组传递给方法,即使数组包含单个元素也是如此。

答案 1 :(得分:1)

您收到该错误是因为您的方法需要一个数组,但是您传入了一个字符串,并且字符串没有each方法。差异是source_names(['one']) vs source_names('one'),注意第一个是包含字符串的数组,而另一个只是一个字符串。如果您希望能够传入无限数量的参数,这听起来像是您想要做的,那么您应该在方法中使用splat *运算符:

def source_names(*packages)
  files = []
  packages.each do |package|
    files << (package + ".ads")
    files << (package + ".adb")
  end
  return files
end

然后你可以称之为,

source_names('one')

source_names('one', 'two')

但除非再次使用splat运算符,否则无法再传递数组

args = ['one', 'two']
source_names(*args)