不确定您真正期望的行为,因为作为@sawa,我认为您也没有applyF{1..4}
平等对待。
这个片段展示了如何依次评估几个 lambda,直到其中一个返回非 false 值而不引发任何东西。
如果您想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
参考:开始块的值是如何确定的?