【问题标题】:Ruby Syntax of '=>' (hashrocket)'=>' (hashrocket) 的 Ruby 语法
【发布时间】:2018-06-08 20:29:38
【问题描述】:

我尝试了这个earlier,每个人都使用了救援块语法。 请不要去那里。给定以下工作代码:

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue Exception => e
   puts "\nCaught exception..."
   puts "Exception class: #{e.class}"
end

在运行时按 CTRL+C 会按预期打印出“Caught exception...”。在救援行中syntax wise究竟发生了什么,特别是在Exception 和变量e 之间以及=> 之间?

“rescue”这个词是一个关键字...... ruby​​ 语言的一部分。 “e”是一个变量,在功能上也可以是“a”、“b”或“c”。下面的代码也同样有效。

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue Exception => b
   puts "\nCaught exception..."
   puts "Exception class: #{b.class}"
end

什么是“例外”和“=>”?是否有另一种方法可以编写此表达式以使其从句法角度更易于理解?我不认为我们在这里处理哈希,因为下面的代码可以编译,但只要按下 CTRL+C 就会抛出错误(未定义的局部变量或方法 `e')。

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue { Exception => b }
   puts "\nCaught exception..."
   puts "Exception class: #{b.class}"
end

有人可以解释发生了什么吗?特别是这个特定示例中的语言元素 '=>' (hashrocket) 是什么,因为它似乎与哈希无关?

【问题讨论】:

    标签: ruby syntax


    【解决方案1】:

    很遗憾地通知您,这只是一次性语法,与其他 Ruby 语法没有任何关系。

    给定表达式:

    begin
      # ...
    rescue FooError, BarError => ex
      # ...
    end
    
    • FooError, BarError 是将被抢救的异常类(通常是StandardError 的子类)的列表。这就像一个参数列表,所以你可以(如果你愿意)做这样的事情:

      my_exception_classes = [ FooError, BarError ]
      
      begin
        # ...
      rescue *my_exception_classes => ex
        # ...
       end
      

      值得注意的是,您通常不应该在这里使用Exception,因为它会拯救所有异常,包括SignalException::InterruptNoMemoryErrorusually isn't what you want

    • => 只是语法,可以说不是语法的最佳选择,因为它会导致类似您自己的问题。

    • ex 是将要放入异常对象的局部变量的名称。

    深入挖掘

    如果您喜欢阅读解析器语法,那么在parse.y 中查看 Ruby 的 YACC 语法总是很有趣。它不是特别容易阅读,但我们可以在这里看到rescue 表达式的语法,在语法中称为opt_rescue

    opt_rescue  : k_rescue exc_list exc_var then
                  compstmt
                  opt_rescue
    

    k_rescue 当然是关键字rescueexc_list 是异常类的列表,就像我说的,就像一个参数列表:

    exc_list    : arg_value
    

    exc_var 是指定放置异常的变量的部分:

    exc_var     : tASSOC lhs
    

    在这里,tASSOC 当然是我们的朋友 hashrocket (=>),lhs,即“左侧”,是您可以在赋值表达式 (比如变量名)。

    compstmt 基本上是“任何有效的 Ruby 代码”,然后又是 opt_rescue,因为您可以(可选地)在 begindef 块中包含许多 rescues

    如您所见,此语法与 Hash 的唯一共同点是 tASSOC

    【讨论】:

    • 如果你用其他东西代替类列表,你会得到一个启发性的错误,例如rescue 2 => ex 给出“救援条款所需的类或模块”。如果定义了b,你会得到与{ Exception => b } 相同的错误,因为它是一个散列。
    • 非常感谢您的简明解释。我曾经为几年前在数字设计课上构建的 4 位计算机发明的一种语言编写了一个递归下降编译器。已经很久很久了,但整个语法讨论对我来说并不陌生。这很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多