Ruby 等同于方案';红宝石中的动态风

Ruby 等同于方案';红宝石中的动态风,ruby,scheme,continuations,Ruby,Scheme,Continuations,Ruby有连续体。。。它是否有一个类似于的动态风的结构?[这个答案是与Scheme程序员一起写的(OP之前在这里问过其他Scheme问题,所以这是一个安全的赌注)。如果你在这里是因为你是一个没有Scheme背景的Ruby程序员,请阅读脚注了解一些上下文。:-] MRI没有(见下文);如果MRI没有,这意味着即使其他实现提供了这种功能,也没有可移植的方式来使用它 我实际上检查了MRI 1.9.1源代码,只是为了确定。在任何情况下,这里有一些代码可以证明,即使是正常的退绕保护(确保)也不能在MRI上

Ruby有连续体。。。它是否有一个类似于

动态风的结构?

[这个答案是与Scheme程序员一起写的(OP之前在这里问过其他Scheme问题,所以这是一个安全的赌注)。如果你在这里是因为你是一个没有Scheme背景的Ruby程序员,请阅读脚注了解一些上下文。:-]

MRI没有(见下文);如果MRI没有,这意味着即使其他实现提供了这种功能,也没有可移植的方式来使用它

我实际上检查了MRI 1.9.1源代码,只是为了确定。在任何情况下,这里有一些代码可以证明,即使是正常的退绕保护(
确保
)也不能在MRI上正常工作(使用1.8.7和1.9.1测试)。(它确实可以与JRuby一起正常工作(我用1.5测试过),因此它显示了它是一个特定于实现的东西。但是请注意,JRuby只提供转义延续,而不是通用的。)

(要使用MRI 1.9+进行测试,您需要使用
-rccontinuation
选项运行,或者将
要求“continuation”
放在文件顶部。)


对于不知道什么是
动态风的读者来说,这是一种指定退出覆盖代码时要运行的代码的方法(非常类似于
确保
),以及重新输入覆盖代码时要运行的代码。(当您在覆盖代码内使用
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
因此,一个正常运行的
dynamic_wind
实现将确保在调用continuation时
$stdout
将被设置回
/dev/null
流,以便在运行
put“This should not show”
的所有实例中,该文本确实不会显示

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