Для чего в 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', то печатается второе поле.
но теперь вы можете видеть разрыв, который BEGIN
(и END
) заполнение блоков: Что делать, если вы хотите сделать что-то безусловно до любой intput был протестирован или после все входные данные были замечены (например, печать заголовка в верхней части отчета или печать строки итогов в конце отчета)? Нормальный awk
линии pattern + action не могут вам помочь.
вот почему BEGIN
и . Но я не уверен, насколько они полезны для современных идиоматических сценариев Ruby. Но, как указывает dbenhur в комментариях, вы все равно можете использовать Ruby очень хорошо для awk
-как один-вкладыши. (У меня также есть воспоминание, что MiniTest, стандартная библиотека тестирования Ruby, использовала at_exit
функция для тестирования, но я не уверен, что она больше не работает.)
два хороших ссылки о Ruby, awk
и рубиновые однострочные:
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