3

我无法确定以下 ruby​​ 内联救援代码有什么问题

def test_check()
p  "first st"
t = 5 * lsdj rescue return false
p "second"
end

p test_check

这给出了一条错误消息 syntax error, unexpected kFALSE, expecting kEND ,但如果我删除赋值语句,它将正常工作(返回 false)。

 def test_check()
    p  "first st"
     5 * lsdj rescue return false
    p "second"
    end

如果出现问题,ruby 中内联救援的正确语法是什么。

4

2 回答 2

12

内联在赋值1,2rescue中使用时不会将语句作为参数——它只需要表达式的值以用于它被救出的情况。

但要小心,你认为这会返回什么?

def q
  return 5 * lsdj rescue false
  true
end

不是false,它返回true。改为这样做,因此救援仅适用于表达式。

def q
  return (5 * lsdj rescue false)
  true
end

这个返回false。


笔记。
1. 这实际上是一个非常好的问题。重述:
      为什么 a = b rescue stmt 是错误而 stmt rescue stmt 不是?
肤浅的答案是,在赋值情况下,rhs 和救援语句是ruby​​ 语法中的arg非终结符而不是完整语句,而在语句情况下,语法只是在救援之后解析完整的stmt规则。这只是它的定义方式。现在,如果你问为什么会这样?...嗯... Ruby 的复杂语法处于yacc(1)的边缘有能力。在我看来,在许多情况下,Matz 详细说明了在某些情况下可以接受的内容,而不仅仅是使用像expr这样的单个非终结符,我想原因是保留语法LALR(1)和将不可避免的转变/减少冲突限制在可容忍的范围内。查看Ruby 源代码分发中的 parse.y 以获得有趣的阅读。
2. 这是一个示例:def q; (t = 5 * lsdj) rescue return false; true; end
这可以按您的意愿工作,因为它恰好与其他语法规则匹配。我听说有些限制是为了支持诗歌模式而存在的。

于 2013-02-27T16:53:45.640 回答
2

您的代码将被解释为:

def test_check()
p  "first st"
t = (5 * lsdj rescue return) false
p "second"
end

这使得false处于无效位置。为了修复它,请放置括号:

def test_check()
p  "first st"
t = 5 * lsdj rescue (return false)
p "second"
end
于 2013-02-27T16:56:24.280 回答