Как определяется значение начального блока? - PullRequest
5 голосов
/ 13 марта 2012

Согласно Языку программирования Ruby стр.164.

Если оператор begin не распространяет исключение, то значение оператора значение последнего выражения , оцененное в предложения begin, rescue или else.

Но я обнаружил, что это поведение согласуется с начальным блоком вместе с оператором else и обеспечивает предложение .

Вот пример кода:

def fact (n)
  raise "bad argument" if n.to_i < 1
end

value = begin
  fact (1)
rescue RuntimeError => e
  p e.message
else
  p "I am in the else statement"
ensure
  p "I will be always executed"
  p "The END of begin block"
end

p value

Вывод:

"I am in the else statement"
"I will be always executed"
"The END of begin block"
"I am in the else statement"
[Finished]

value оценивается как условие else . Это противоречивое поведение, поскольку обеспечивает предложение - последний выполненный оператор.

Может ли кто-нибудь объяснить, что происходит в начале блока?

Ответы [ 3 ]

4 голосов
/ 13 марта 2012

Я бы интерпретировал цель блока begin/rescue/else/end как:

  • Выполните код в секции begin, а затем код в секции else.
  • Если что-то идет не так в секции begin, вместо секции else выполните секцию rescue.

Так что либо секция rescueили секция else будет выполнена после попытки секции begin;поэтому имеет смысл, что один из них будет использоваться как значение целого блока.

Это просто побочный эффект, что секция ensure всегда будет выполняться.

val = begin
  p "first"; "first"
rescue => e
  p "fail"; "fail"
else
  p "else"; "else"
ensure
  p "ensure"; "ensure"
end

val # => "else"
# >> "first"
# >> "else"
# >> "ensure"

Но:

val = begin
  p "first"; "first"
  raise
rescue => e
  p "fail"; "fail"
else
  p "else"; "else"
ensure
  p "ensure"; "ensure"
end

val # => "fail"
# >> "first"
# >> "fail"
# >> "ensure"
0 голосов
/ 13 марта 2012

В этом случае блок begin - это просто способ определения раздела, для которого вы можете захотеть выполнить обработку исключений.

Помните, что else в этом случае выполняется, если не возникает исключений, иensure будет работать независимо от исключений или их отсутствия.

0 голосов
/ 13 марта 2012

Я просто догадываюсь здесь, но поскольку целью блока обеспечения является завершение любых ресурсов, которые могут оставаться открытыми (очистка другими словами), и поэтому имеет смысл, что логическое значение должно быть результатом else заявление. Это имеет смысл для меня, что это по замыслу.

...