[这个答案是由计划程序员编写的(OP之前曾在此处提出其他方案问题,因此这是一个安全的选择).如果你在这里因为你是一个没有Scheme背景的Ruby程序员,请阅读脚注以获取一些上下文.:-)]
MRI没有(见下文); 如果MRI没有,这意味着即使另一个实现提供它,也没有可移植的方式来使用任何这样的功能.
我确实检查了MRI 1.9.1源代码.在任何情况下,这里都有一些代码来证明即使正常的展开保护(ensure)也不能正确地连续MRI(用1.8.7和1.9.1测试).(它与JRuby(我用1.5测试)一起工作正常,所以它表明它是一个特定于实现的东西.但请注意,JRuby只提供转义延续,而不是通用的.)
callcc do |cc|
begin
puts 'Body'
cc.call
ensure
puts 'Ensure'
end
end
Run Code Online (Sandbox Code Playgroud)
(要使用MRI 1.9+进行测试,您需要使用该-rcontinuation选项运行,或者放在require 'continuation'文件的顶部.)
对于不知道是什么的读者来说dynamic-wind,这是一种指定在被覆盖的代码退出时运行的代码(非常类似ensure)的方法,以及在重新输入所覆盖的代码时要运行的代码.(当您call/cc在覆盖的代码中使用时,可能会发生这种情况,并在退出覆盖的代码后调用continuation对象.)
完全做作的例子:
def dynamic_wind pre, post, &block
raise 'Replace this with a real implementation, kthx'
end
def redirect_stdout port, &block
saved = $stdout
set_port = lambda {$stdout = port}
reset_port = lambda {$stdout = saved}
dynamic_wind set_port, reset_port, &block
end
cc = nil
# cheap way to nuke all the output ;-)
File.open '/dev/null' do |null|
redirect_stdout null do
callcc {|cc|}
puts 'This should not be shown'
end
puts 'This should be shown'
cc.call
end
Run Code Online (Sandbox Code Playgroud)
因此,正常运行的dynamic_wind实现将确保在调用continuation时$stdout将其设置回流/dev/null,以便在puts 'This should not be shown'运行的所有实例中,确实不显示该文本.
| 归档时间: |
|
| 查看次数: |
331 次 |
| 最近记录: |