Подтвердить что ты не робот

Каковы зарезервированные слова BEGIN или END, используемые в Ruby?

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

 BEGIN{puts x = 10}
 10
4b9b3361

Ответ 1

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

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

puts times_3(gets.to_i)

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

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

END { 
  puts "Bye!" 
}

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

Блоки BEGIN и END

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

BEGIN {   
  begin code 
}

END {
  end code 
}

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

Ответ 2

Одна вещь, о которой не упоминалось, заключается в том, что в ранних версиях 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 $1 }
/bar/ { print $2 }

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

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

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

Две хорошие ссылки о Ruby, awk и Ruby one-liners:

Ответ 3

От Язык программирования 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

Ответ 4

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

Это пример.

puts "Goodbye cruel world!"

BEGIN {
puts "Hello World!"
}

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

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

Ответ 5

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

cat <<EOF > numbers
1
5 
10
20
EOF

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

обратите внимание на то, как BEGIN возвращает глобальное значение, а END печатает результат.