我可以很好地迭代一个数组:
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 :我知道字符串不支持数组方法。我的困惑是为什么我有时会得到一个数组,而是一个字符串来代替单个元素数组。
答案 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)