为什么a = b rescue stmt是错误但stmt rescue stmt不是?

时间:2013-02-27 16:43:57

标签: ruby syntax syntax-error

我无法确定跟随红宝石内联救援代码的错误

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中内联救援的正确语法是什么。

2 个答案:

答案 0 :(得分:12)

内联rescue在赋值 1,2 中使用时不会将语句作为参数 - 它只需要一个表达式的值作为它得到了救援。

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

def q
  return 5 * lsdj rescue false
  true
end

false,它返回 true 。不管这样做,救援只适用于表达。

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

这个返回 false。


便笺。
1。这实际上是一个非常好的问题。重申:
为什么 a = b救援计划 错误,但 stmt rescue stmt 是不是?
表面上的答案是,在赋值情况下,rhs和rescue语句在ruby语法中是 arg 非终结符而不是完整语句,而在语句中例如,语法只是在救援后解析完整的 stmt 规则。这就是它的定义方式。现在,如果你再问为什么? ......好吧...... Ruby的复杂语法生活在 yacc(1) 能力的边缘。在我看来,在很多情况下,Matz详细说明了在某些情况下可以接受的内容,而不仅仅是使用像 expr 这样的单一非终端,我想是保留原因语法 LALR(1) 并将不可避免的shift/reduce conflicts限制为可容忍的空间。 Ruby源代码分发中的 Check out parse.y 进行了有趣的阅读。
2。下面是一个示例:def q; (t = 5 * lsdj) rescue return false; true; end这可以按照您的意愿工作,因为它恰好与其他语法规则匹配。我听说有一些限制是为了支持诗歌模式。

答案 1 :(得分: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