1

我正在阅读“The Ruby Programming Language”并想尝试书中提供的示例(第 6 章,改变控制流,catch 和 throw),以使用 catch/throw 打破嵌套循环:

for matrix in data do 
  catch :missing_data do
    for row in matrix do 
      for value in row do
        throw :missing_data unless value
        puts value
      end
    end
  end
end

我将数据定义为三个矩阵的数组:

数据 => [[[2, 3, 7], [8, 9, 10], [0, 1, 4]], [["a", "b", "c"], ["d", false, "e"], ["f", "g", nil]], [["abc", "def"], ["ghi", "jkl"]]]

然而,当我在 IRB(版本 1.9.3p327)中尝试代码时,我得到一个“意外的 $end,期待 keyword_end”错误。我尝试过使用代码并发现如果我删除最外面的(即 for)循环它可以工作,但是使用循环我得到了错误。为了仔细检查,我创建了一个更简单的循环:

for i in [1,2,3] do
  catch :two do
    if i==2 then throw :two end
  end
end

再次,我得到相同的情况:for循环出错,没有for循环没有错误(实际上,使用IRB,我没有机会进入最后一个'end',但进入第四个后得到错误上一行)。

有谁知道我为什么会收到这个错误?

4

3 回答 3

3

你不需要do. for ... in ...这实际上是一个语法错误。那是你的问题。catch与/无关throw。只需do从所有for循环中删除。

工作示例:

for matrix in data 
  catch :missing_data do
    for row in matrix 
      for value in row
        throw :missing_data unless value
        puts value
      end
    end
  end
end

编辑:

这是一个 IRB 问题。当我将您的代码放入脚本中时,它可以完美运行。

于 2013-01-29T22:37:21.487 回答
3

这似乎是构建和/或环境相关的(我倾向于环境):

  • 当我从 Sublime Text 2 中执行原始代码时,它可以工作
  • ruby从命令行运行时,原始代码有效
  • 当我输入原始代码时,它不起作用irb

irb将 the放入doexternal 中for,或使用{}for the catch,可以:

$ rvm use 1.9.3-p327                                                                              Using /Users/Dave/.rvm/gems/ruby-1.9.3-p327
$ irb
irb(main):001:0> data = [[[2, 3, 7], [8, 9, 10], [0, 1, 4]], [["a", "b", "c"], ["d", false, "e"], ["f", "g", nil]], [["abc", "def"], ["ghi", "jkl"]]]
irb(main):002:0> for matrix in data do
irb(main):003:1*   catch(:missing_data) {
irb(main):004:2*     for row in matrix do 
irb(main):005:3*       for value in row do
irb(main):006:4*         throw :missing_data unless value
irb(main):007:4>         puts value
irb(main):008:4>       end
irb(main):009:3>     end
irb(main):010:2>   }
irb(main):011:1> end
2
3
7
8
9
10
0
1
4
a
b
c
d
abc
def
ghi
jkl
于 2013-01-29T22:37:43.037 回答
0

正如我在评论中所说,do从你的for陈述中删除。

于 2013-01-29T22:49:55.913 回答