另一个“ nil:NilClass的未定义方法'[] ='”错误

时间:2019-10-23 15:18:54

标签: ruby

此代码有什么问题?

我有一个.txt文件,其中包含一些这样的属性:

attr_one, att2, attr3, attr4
attr_one, att2, attr3, attr4
attr_one, att2, attr3, attr4

我想将“ attr1”更改为“ attr_one”

require "csv"
people = CSV.read("text.txt")
attr_one = people.find { |person| person[0] =~ /attr_one/ }
attr_one[0] = "attr_one_new"

CSV.open("text.txt", "w") do |csv|
    people.each do |person|
        csv << person
    end
end

以及如何更改它以启动前面的代码?

attr_one[0]...

这是一本参考手册中的示例。

此代码的输出应为如下数组:

attr_one, att2, attr3, attr4
attr_one_new, att2, attr3, attr4
attr_one, att2, attr3, attr4

哪里有错?

1 个答案:

答案 0 :(得分:0)

问题在于find返回nil,因为该块从不返回真实值。

attr_one = people.find { |person| person[0] =~ /attr_one/ }

这将导致调用以下行。

attr_one[0] = "attr_one_new"

因为nil没有[]=的设置器。

这里的收获是find可以返回nil值。

documentation说:

  

find(ifnone = nil){| obj |块}→obj或nil

     

查找(ifnone = nil)→an_enumerator

     

枚举中的每个条目传递给 block 。返回第一个 block   不是假的。如果没有对象匹配,则调用 ifnone 并返回其   指定时返回结果,否则返回nil

     

如果没有给出块,则返回一个枚举数。

(1..100).detect  #=> #<Enumerator: 1..100:detect>
(1..100).find    #=> #<Enumerator: 1..100:find>

(1..10).detect   { |i| i % 5 == 0 and i % 7 == 0 }   #=> nil
(1..10).find     { |i| i % 5 == 0 and i % 7 == 0 }   #=> nil
(1..100).detect  { |i| i % 5 == 0 and i % 7 == 0 }   #=> 35
(1..100).find    { |i| i % 5 == 0 and i % 7 == 0 }   #=> 35