23

这是一个很难找到的词,因为在大多数情况下,它们在搜索过程中并不敏感。在文档之外我能找到的最好的方法是在 IRB 中进行测试。

 BEGIN{puts x = 10}
 10
4

6 回答 6

23

由于所有关键字 BEGINEND被记录为公共实例方法Object(即使您不会看到它们从Object.public_instance_methods)返回

BEGIN通过代码块指定在程序开始顺序执行之前无条件执行的代码。有时用于模拟对方法的前向引用。

puts times_3(gets.to_i)

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

END通过代码块指定要在程序终止之前执行的代码。

END { 
  puts "Bye!" 
}

Programming Ruby The Pragmatic Programmer's Guide中的一些更详细的解释

BEGIN 和 END 块

每个 Ruby 源文件都可以声明要在文件加载时(BEGIN 块)和程序完成执行后(END 块)运行的代码块。

BEGIN {   
  begin code 
}

END {
  end code 
}

一个程序可能包含多个 BEGIN 和 END 块。BEGIN 块按照遇到的顺序执行。END 块以相反的顺序执行。

于 2013-03-10T19:03:18.507 回答
19

没有提到的一件事是,在早期版本的 Ruby 中,BEGIN是无条件的:

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

如果您在 Ruby 1.8.7 中尝试这样做,则会打印该句子,即使它位于if未采用的分支中。

BEGIN在 Ruby 2.0.0 下,在顶层之外使用是一个语法错误(一种更聪明的处理方法):

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

编辑:在某种程度上,没有人回答您在评论中提出的问题:为什么 Ruby 有BEGIN?我会尽力。从PerlBEGIN来到 Ruby(就像很多东西一样)。Perl 有它,因为它存在于. 这很有意义,因为默认情况下,文件由一系列模式和操作组成:awkawkawk

/foo/ { print $1 }
/bar/ { print $2 }

对每一行检查每个模式。如果模式匹配,则执行操作。否则,awk继续下一个模式。因此,在上面的迷你脚本中,如果该行匹配 'foo',则打印第一个字段。如果该行与“bar”匹配,则打印第二个字段。

但是现在您可以看到BEGIN(and ) 块填补的空白:如果您想在测试任何输入之前END看到所有输入之后无条件地做某事(例如在报告顶部打印标题或打印报告末尾的一排总计)?模式+动作的正常线条无法帮助您。awk

这就是为什么BEGINEND存在。但我不确定它们对于现代、惯用的 Ruby 脚本有多大用处。但正如 dbenhur 在评论中指出的那样,您仍然可以很好地将 Ruby 用于类似awk的单行代码。(我还记得标准的 Ruby 测试库 MiniTest 曾经使用at_exit函数进行测试,但我不确定它是否会不再使用。)

awk关于 Ruby和 Ruby one-liners 的两个很好的链接:

于 2013-03-10T20:03:56.720 回答
7

来自Ruby 编程语言:


BEGINEND

每个 Ruby 源文件都可以声明要在文件加载(BEGIN块)和程序完成执行后(END块)运行的代码块。

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

一个程序可能包括多个BEGINEND块。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
于 2013-03-10T19:03:44.110 回答
5

BEGIN 块正是您可能假设的,即给定的块将在程序中的其余代码之前运行。

这是一个例子。

puts "Goodbye cruel world!"

BEGIN {
puts "Hello World!"
}

我希望这会有所帮助。

在 minitest 中有一个工作示例,其中一组值被放在文件末尾,但首先评估。

于 2013-03-10T19:03:43.263 回答
2

使用 -e 选项处理流时,BEGIN/END 非常方便。例如,汇总一个数字文件:

cat <<EOF > numbers
1
5 
10
20
EOF

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

注意 BEGIN 如何将全局归零,而 END 打印结果。

于 2014-07-16T01:40:23.217 回答
0

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

于 2017-01-06T14:12:08.093 回答