比较CSV :: Row对象与单件nil和使用nil?

时间:2013-08-22 18:33:27

标签: ruby csv ruby-1.9.3

所以我在Ruby 1.9.3-p374中生成一个包含CSV::Row个对象和nil的数组,如下所示:

 csv_array = [nil, #<CSV::Row "name":John>, nil, nil, #<CSV::Row "name":John>]

以下代码行正常工作:

 csv_array.delete_if { |x| x.nil? }

但是这一行给出了一个错误:

 csv_array.delete_if { |x| x==nil }

错误:

.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/csv.rb:478:in `==': undefined method `row' for nil:NilClass (NoMethodError)

关于为什么会出现这种情况的任何想法?我认为==nil.nil?会产生相同的结果。

2 个答案:

答案 0 :(得分:0)

  

我以为== nil和.nil?会产生相同的结果。

是的,他们正在给予。看下面的例子:

require 'csv'

c1 = CSV::Row.new(["h1","h2","h3"],[1,2,3])
# => #<CSV::Row "h1":1 "h2":2 "h3":3>
c2 = CSV::Row.new(["h1","h3","h4"],[1,2,3])
# => #<CSV::Row "h1":1 "h3":2 "h4":3>
[nil,c1,c2].delete_if { |x| x.nil? }
# => [#<CSV::Row "h1":1 "h2":2 "h3":3>, #<CSV::Row "h1":1 "h3":2 "h4":3>]
[nil,c1,c2].delete_if { |x| x==nil }
# => [#<CSV::Row "h1":1 "h2":2 "h3":3>, #<CSV::Row "h1":1 "h3":2 "h4":3>]
c1.respond_to?(:nil?) # => true
c1.respond_to?(:==) # => true
c1==nil # => false
c1.nil? # => false

您怀疑为错误的代码非常完美。但是从第'==': undefined method 'row' for nil:NilClass (NoMethodError)行可以清楚地看出,您使用了代码something == something.row中的其他位置,其中somethingnil。因此,您收到错误,因为NilClass没有任何#row方法。

答案 1 :(得分:0)

CSV::Row会覆盖==,并且实现会假定您要比较的内容也是CSV::Row。如果你传递任何不属于那个级别的东西,它可能会爆炸。

你可能会认为这是不好的做法,并且在这种情况下它应该返回false而不是炸毁(这看起来在ruby 2.0中已经改变了)

另一方面,

nil?没有被覆盖,因此按预期工作。