Ruby中使用的保留字BEGIN或END是什么?

时间:2013-03-10 18:54:33

标签: ruby reserved-words

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

 BEGIN{puts x = 10}
 10

6 个答案:

答案 0 :(得分:23)

由于所有keywords BEGINEND都记录为public instance methods of 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块   逆序。

答案 1 :(得分:19)

有一件事没有提到,在早期版本的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?我会尽力。来自PerlBEGIN来自Ruby(就像许多事情一样)。 Perl拥有它,因为它存在于awk中。它在awk中很有意义,因为默认情况下,awk文件包含一系列模式和操作:

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

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

但是到现在为止,您可以看到BEGIN(和END)阻止填充的差距:如果您想在任何输入测试之前无条件地执行某些操作,该怎么办? 之后看到所有输入(比如在报告顶部打印标题或在报告末尾打印一行总计)?正常awk行模式+动作无法帮助你。

这就是BEGINEND存在的原因。但我不确定它们对于现代的,惯用的Ruby脚本有多么有用。但正如dbenhur在评论中指出的那样,你仍然可以很好地使用Ruby awk - 就像单行一样。 (我还记得MiniTest,标准的Ruby测试库,曾经使用at_exit函数进行测试,但我不确定它会再用了。)

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

答案 2 :(得分:6)

来自 The Ruby Programming Language:


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

答案 3 :(得分:5)

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

这是一个例子。

puts "Goodbye cruel world!"

BEGIN {
puts "Hello World!"
}

我希望有所帮助。

在minitest中有一个working example,其中一组值被放在文件末尾,但首先进行评估。

答案 4 :(得分: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打印结果。

答案 5 :(得分: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