1

たとえば、シンボルの配列から動的blockに/ rescuelikeのチェーンを構築することは可能ですか。以下のコードは、私が静的に書くものを模倣することになっています:[:f1, :f2, :f3, f4]

  begin
    applyF1()
  rescue
    applyF2()
    begin
      applyF3()
    rescue
      applyF4()
    end
  end

object.send(message)シンボル ( )からビルドされたメッセージを送信する方法は既に知っているのでapplyFx、問題ではありません。

4

2 に答える 2

1

@sawaとして、あなたがapplyF{1..4}平等に扱っているとは思えないので、あなたが本当に期待した行動がわからない.

このスニペットは、いくつかのラムダを順番に評価し、そのうちの 1 つが何も発生させずに false 以外の値を返す方法を示しています。

applyF{1..?}ペアで評価したい場合(F1失敗した場合は で回復しF2、失敗した場合は でF3回復し、など)、常に nil を返すF4ようにすることができます。applyF{2,4,..}

#!/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

参照 :開始ブロックの値はどのように決定されますか?

于 2013-06-04T00:50:44.390 に答える
0

これは私の頭に浮かぶ最初のものです:

def rescueChain(*args)
  args.each do |f|
    begin
      <... apply f here ...>
      return  # Exits from the entire function.
    rescue
    end
  end
end

まだテストしていません。

于 2013-06-03T23:56:20.150 に答える