Рубиновый синтаксис '=>' (hashrocket) - PullRequest
0 голосов
/ 08 июня 2018

Я попробовал это ранее , и все вышли на синтаксис блока спасения. Пожалуйста, не ходи туда .С учетом следующего рабочего кода:

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 во время его работы выводит «Поймано исключение ...», как и ожидалось.Что именно происходит с синтаксисом в строке спасения, особенно между Exception и переменной e с => между ними?

Слово "спасение" является ключевым словом ... частью языка рубина.«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) используется в этом конкретном примере, поскольку он, похоже, не имеет ничего общего с хешами?

1 Ответ

0 голосов
/ 09 июня 2018

Извините, что сообщаю, что это всего лишь одноразовый синтаксис, который на самом деле не имеет никакого отношения к другому синтаксису Ruby.

С учетом выражения:

begin
  # ...
rescue FooError, BarError => ex
  # ...
end
  • FooError, BarError - список классов исключений (обычно подклассы StandardError), которые будут спасены.Это ведет себя так же, как список аргументов, так что вы можете (если хотите) сделать что-то вроде этого:

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

    Стоит отметить, что вы, как правило, не должны использовать Exception здесь, потому что это спасет все исключения, включая такие вещи, как SignalException::Interrupt и NoMemoryError, которые обычно не то, что вы хотите .

  • => - это всего лишь синтаксис и, возможно, не лучший выбор синтаксиса, поскольку он приводит к таким вопросам, как ваш.

  • ex - это имя локальной переменной, в которую будет помещен объект исключения.

Копание глубже

Если вы читаете грамматику синтаксического анализатора, это всегда интереснов грамматике YACC Руби в parse.y.Это не особенно легко прочитать, но мы можем увидеть грамматику для выражения rescue, называемого opt_rescue в грамматике, здесь:

opt_rescue  : k_rescue exc_list exc_var then
              compstmt
              opt_rescue

k_rescue имеетконечно ключевое слово rescue.exc_list - это список классов исключений, который, как я уже сказал, аналогичен списку аргументов:

exc_list    : arg_value

exc_var - это часть, в которой указана переменная для помещения исключения:

exc_var     : tASSOC lhs

И здесь tASSOC - это, конечно, наш друг hashrocket (=>), а lhs, то есть «левая сторона», это выражение, которое вы найдете слева отвыражение присваивания (как, скажем, имя переменной).

compstmt - это, по сути, «любой допустимый код Ruby», а затем снова есть opt_rescue, поскольку вы можете (необязательно) иметь много rescues в блоке begin или def.

Как видите, единственное, что этот синтаксис имеет общего с хэшем, это tASSOC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...