理解多维数组中的奇怪输出

时间:2014-08-25 00:01:10

标签: ruby arrays multidimensional-array

我是ruby的新手,我试图迭代一个二维数组。我在代码中犯了一个错误。从那个错误中,我注意到了一些意想不到的输出。

s = [["ham", "swiss"], ["turkey", "cheddar"], ["roast beef", "gruyere"]]
i = 0;
s.each{
    |array| so = array[i] # pin
    puts so[i]
    }

由于#pin,如果i = 0,则输出为h t r。 i = 1给出了w h r。我> 1给出错误:

C:/Ruby.rb in `block in <main>': undefined method `[]' for nil:NilClass (NoMethodError)
    from C:/Ruby.rb:3:in `each'
    from C:/Ruby.rb:3:in `<main>'

如果我使用|array| so = array # pin,那么我的代码不会产生奇怪的输出。我将修复剩余的东西,让我的代码迭代所有'我'可以拥有的值。

请解释一下。

PS:工作代码在这里

s = [["ham", "swiss"], ["turkey", "cheddar"], ["roast beef", "gruyere"]]
s.each{
  |array| so = array
  array.each{
  |str| puts str   
  }
}

2 个答案:

答案 0 :(得分:0)

对于每种类型的三明治,当我为0时,第一个元素也是肉。所以[0]是肉的第一个字母。

当我是1,这是第二个元素,这是奶酪。所以[1]是奶酪的第二个字母。

当我3岁时,三明治没有第三个成分。零也是如此。所以[2]要求零[2]。

nil是一个类,就像红宝石中的所有东西一样。但是nil没有实现[]方法,因为实现Enumerable模块的数组和其他类可以实现。

由于nil不支持[]方法,因此会得到未定义的方法错误。

即使是内置于其他语言中的操作,如+,[]和==,也是可以在Ruby中重写的方法。

要准确了解发生了什么,请尝试以下代码:

class NilClass
  def [] (i)
    nil
  end
end

执行该操作将打开现有的NilClass,并添加一个名为[]的方法。然后你可以做nil [1]它将返回nil。更改像这样的现有类在Ruby世界中被称为 monkey patching

答案 1 :(得分:0)

当您要求so[2]时,您实际上是在询问第三个元素,如果它不存在,您将收到错误。

我建议像这样构建你的块:

s.each do |pair|
  puts pair
end

请注意do/end而不是{},并且迭代变量的位置与each内联。另请注意,这相当于您的工作代码&#34;所以在这种情况下你不需要额外的迭代器。