Для чего в Ruby используются зарезервированные слова BEGIN или END?

это очень трудно найти слово, потому что в большинстве случаев они не чувствительны во время поиска. Лучшее, что я мог найти вне документации, - это тест в IRB.

 BEGIN{puts x = 10}
 10

6 ответов


, как все ключевые слова BEGIN и END описаны как методы открытого экземпляра Object (хотя вы не увидите, как они возвращаются из Object.public_instance_methods)

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

puts times_3(gets.to_i)

BEGIN {
  def times_3(n)
    n * 3
  end
}

конец обозначает, через код блок, код должен быть выполнен непосредственно перед завершением программы.

END { 
  puts "Bye!" 
}

более подробное объяснение от программирование на Ruby руководство прагматичного программиста

начало и конец блоков

каждый исходный файл Ruby может объявлять блоки кода для запуска как файл загружается (блоки BEGIN) и после того, как программа закончено выполнение (конечные блоки).

BEGIN {   
  begin code 
}

END {
  end code 
}

программа может включать несколько блоков начала и конца. Начать блоки выполняются в том порядке, в котором они встречаются. Конечные блоки выполняются в обратный порядок.


одна вещь, которая не была упомянута, что в более ранних версиях Ruby,BEGIN была безоговорочной:

if false
  BEGIN { puts "Up is down, hot is cold, good is evil!" }
end

если вы попробуете это с Ruby 1.8.7, предложение будет напечатано, даже если оно находится в ветви if это не принято.

в Ruby 2.0.0 это синтаксическая ошибка для использования BEGIN вне верхнего уровня (гораздо более умный способ справиться с этим):

unconditional.rb:2: BEGIN is permitted only at toplevel
  BEGIN { puts "Up is down, hot is cold, good is evil!" }
       ^

редактировать: таким образом, никто не ответил на вопрос, который вы поднимите в своем комментарии: Почему у Ruby есть BEGIN на всех? Я постараюсь. BEGIN приходит к Ruby (как и многие вещи) из Perl. Perl имеет его, потому что он существовал в awk. Это имело тонну смысла в awk потому что по умолчанию awk файл состоит из ряда шаблонов и действий:

/foo/ { print  }
/bar/ { print  }

каждый шаблон проверяется для каждой строки. Если шаблон совпадает, то выполняется действие. В противном случае, awk переходит к следующей схеме. Так в мини-скрипте выше, если строка соответствует "foo", то печатается первое поле. Если строка соответствует 'bar', то печатается второе поле.

но теперь вы можете видеть разрыв, который BEGINEND) заполнение блоков: Что делать, если вы хотите сделать что-то безусловно до любой intput был протестирован или после все входные данные были замечены (например, печать заголовка в верхней части отчета или печать строки итогов в конце отчета)? Нормальный awk линии pattern + action не могут вам помочь.

вот почему BEGIN и . Но я не уверен, насколько они полезны для современных идиоматических сценариев Ruby. Но, как указывает dbenhur в комментариях, вы все равно можете использовать Ruby очень хорошо для awk-как один-вкладыши. (У меня также есть воспоминание, что MiniTest, стандартная библиотека тестирования Ruby, использовала at_exit функция для тестирования, но я не уверен, что она больше не работает.)

два хороших ссылки о Ruby, awk и рубиновые однострочные:


С Язык Программирования Ruby:


BEGIN и END блоки

каждый исходный файл Ruby может объявлять блоки кода для запуска при загрузке файла (BEGIN блоки) и после завершения выполнения программы (тег END блоки).

BEGIN {
  # begin code
} 
END {
  # end code
}

программа может включать несколько BEGIN и END блоки. BEGIN блоки выполняются в порядке их следования. END блоки выполняются в обратном порядке.


так:

$ cat beginend.rb
END { puts :end }
BEGIN { puts :begin }
END { puts :end2 }
BEGIN { puts :begin2 }

puts :run
$ ruby beginend.rb 
begin
begin2
run
end2
end

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

Это пример.

puts "Goodbye cruel world!"

BEGIN {
puts "Hello World!"
}

надеюсь, это поможет.

есть пример работающего этого в minitest, где коллекция значений помещается в конец файла, но сначала оценивается.


начало / конец очень удобно при использовании опции-e для обработки потока. Например, чтобы суммировать файл чисел:

cat <<EOF > numbers
1
5 
10
20
EOF

cat numbers | ruby -ane 'BEGIN { $t=0}; END {puts $t}; $t += $_.to_i'

обратите внимание, как начальные нули выходят из глобального, а конец печатает результат.


BEGIN и END также используется для комментариев, таких как:

=begin
This is a comment line
It can explain what the rest of the program is about
This was inspired from the perl style of programming
=end

вы можете проверить то же самое здесь: https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Comments