是否可以构建一个block
/ rescue
链,就像这个动态一样,例如来自符号数组[:f1, :f2, :f3, f4]
。下面的代码应该模仿我写的静态:
begin
applyF1()
rescue
applyF2()
begin
applyF3()
rescue
applyF4()
end
end
我已经知道如何从符号(object.send(message)
)发送内置消息,因此applyFx
不是问题。
答案 0 :(得分:1)
不确定你真正期望的行为,因为@sawa,我不认为你同样对待applyF{1..4}
。
此代码段显示了如何依次评估一些lambda,直到其中一个lambdas返回非假值而不提高任何值。
如果您要成对评估applyF{1..?}
(F1
失败时,请按F2
进行恢复,然后尝试使用F3
并在失败时按F4
进行恢复,等等),你可以让applyF{2,4,..}
总是返回nil。
#!/usr/bin/env ruby
blocks = {
a: ->(){ raise "raise" },
b: ->(){ raise "also raise" },
c: ->(){ :finished },
d: ->(){ "won't be executed" },
}
ret = blocks.reduce(nil) do |has_succeeded, (key, lam)|
has_succeeded ||=
begin
puts "trying #{key.inspect}"
lam.call # when succeed, the lambda should return a non-false value
rescue => e
puts "failed with message=<#{e.message}>. trying next"
nil
# no else clause here, so
# if lam.call raises nothing, memo keep its return value, and prevents calling following {lam}s.
# if something is raised in lam.call, this block evalutes to nil
end
end
# will print:
# trying :a
# failed with message=<raise>. trying next
# trying :b
# failed with message=<also raise>. trying next
# trying :c
p ret
# => :finished
答案 1 :(得分:0)
这是我想到的第一个:
def rescueChain(*args)
args.each do |f|
begin
<... apply f here ...>
return # Exits from the entire function.
rescue
end
end
end
我还没有测试过。