在Ruby中,为什么会出现"undefined method [] for nil:NilClass (NoMethodError)"这个错误?

3

这是我的代码:

begin
     items = CSV.read('somefile.csv')
     linesAmount = CSV.readlines('somefile.csv').size
     counter = 1
     while linesAmount >= counter do
       fullrow = items[counter]
       firstitem = fullrow[0] #This is the line that my code doesn't like.
       puts firstitem
       counter = counter + 1

     end


end

对于某些人来说,Ruby似乎不喜欢那一行,即我有firstitem = fullrow [0]。它会抛出未定义的方法[]错误。但是,在控制台中,我仍然可以看到它打印出了第一个项目...所以它仍然会打印它,但是还会抛出错误?到底怎么回事?
然而,如果我将while循环中的前三行放在while循环外,并注释掉循环中的所有内容,除了计数器行,那么我就不会得到任何错误。因此,如果firstitem行出现在while循环之外,代码认为一切正常。
编辑:我知道数组从0开始,但我特意希望计数器不关心第一行。我忘了提到,抱歉。
编辑2:谢谢大家,我通过在linesAmount后添加-1解决了它,现在它可以运行了!

Ruby中的数组是从零开始的。当counter == linesAmount时,它是第linesAmount+1行,而items[counter]是可预测的nil。因此,fullrow为空,导致错误。你在控制台上看到的是前一个循环打印出来的值。顺便说一句,整个代码看起来太像PHP了。在这里使用items.each会更合适。 - Aleksei Matiushkin
请不要在问题中直接给出答案。 - anon
2个回答

1

看起来你有一个偏移量错误,你正在读取超过items数组的末尾。如果CSV文件中有10行,则这些行将是一个索引从0到9而不是1到10的数组。

将你的while循环修改为以下内容

counter = 0
while counter < linesAmount
  ...
end

然而,总体而言,更好的方法是只需执行以下操作。
CSV.readlines('somefile.csv').each do |line|
  puts line
end

条件 counter <= linesAmount 将运行 0 到 10 次,仍会引发异常。 - BroiSatse
1
你是对的,你恰好在错误的时间到达,我认为在我编辑更正之前大约有20秒钟左右。 - Marc

1

CSV.readCSV.readlines 返回数组。如果您的数组包含两个值,则 size 返回 2。但是您需要调用的索引是 items[0]items[1]。因此,这一行

items[counter]

抛出一个错误。

将该行更改为

items[counter - 1]

而且它应该可以正常工作。

此外,您可以通过使用Ruby惯用语来改进您的代码:

begin
 items = CSV.read('somefile.csv')
 items.each do |item|
   puts item[0]
 end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接