Kernel#at_exit方法和END(全部大写)关键字之间存在哪些差异(如果有)?后者仅仅是一种更 Perlish 的做事方式,而前者更像 Ruby 风格吗?
我试过做defined?(END {puts "Bye"})
,但出现语法错误。
Kernel#at_exit方法和END(全部大写)关键字之间存在哪些差异(如果有)?后者仅仅是一种更 Perlish 的做事方式,而前者更像 Ruby 风格吗?
我试过做defined?(END {puts "Bye"})
,但出现语法错误。
“The Ruby Programming Language”定义了它们行为的细微差别。at_exit
在循环内可以多次调用,每次迭代调用都会在代码退出时执行。END
只会在循环内调用一次。
...如果 END 语句在循环中并且执行了多次,则与之关联的代码仍然只注册一次:
a = 4;
if (true)
END { # This END is executed
puts "if"; # This code is registered
puts a # The variable is visible; prints "4"
}
else
END { puts "else" } # This is not executed
end
10.times {END { puts "loop" }} # Only executed once
内核方法 at_exit 提供了 END 语句的替代方案;它在解释器退出之前注册一个要执行的代码块。与 END 块一样,与第一个 at_exit 调用关联的代码将最后执行。如果在一个循环中多次调用 at_exit 方法,则与它关联的块将在解释器退出时执行多次。
所以,运行:
2.times {
END { puts 'END'}
at_exit { puts 'at_exit' }
}
结果是:
at_exit at_exit 结尾
在方法内部使用END
会产生警告,而at_exit
不会产生警告(尽管两者仍然有效):
def with_end
END {puts 'with END'}
end
def with_at_exit
at_exit {puts 'with at_exit'}
end
with_end
with_at_exit
输出:
$ ruby foo.rb
foo.rb:2: warning: END in method; use at_exit
with at_exit
with END
在不太实用的层面上,END
是语言关键字,at_exit
是语言中的方法。