2009-07-29 25 views
4

私は、そのリソースに対して保持されているロックの下でブロックパラメータを実行するrunメソッドを持ついくつかのリソースオブジェクトを持っているとします。たとえば、次のように:ruby​​ブロックの動的ネスト

r = Resource("/tmp/foo") 
r.run { ... } 

どのように私は次のように、リソースの配列を受け取り、すべてのリソースのために開催されたロックの下にそのブロックのパラメータを実行ルビーメソッドを書くことができます:

def using_resources(*res, &block) 
    r[0].run do; r[1].run do; r[2].run do ... 

    yield; 

    end; end; end; ... 
end 

がそれです可能ですか?

答えて

8

コードで、これが最善ここで再帰

を使用して行われているように私には思える:「、これ

using_resources Resource.new('/tmp'), Resource.new('http://stackoverflow.com') do 
    do_some_processing 
end 

あなたが言う:

def using_resources(*res, &block) 

    first_resource = res.shift 

    if res.length > 0 
    first_resource.run do 
     using_resources(*res, &block) 
    end 
    else 
    first_resource.run do 
     block.call 
    end 
    end 

end 

だから同じように使用リソースの配列を取る。すでにArrayを持って、それを使用する必要がある場合は、コールの外Arrayをスプラットすることができ、次のいずれか

using_resources *my_array do 
    do_some_processing 
end 

それとも、どちらかArrayまたはResourceのリストでそれを呼び出すことができますメソッド定義、内部をS:

def using_resources(*res, &block) 
    res = [*res] 
    # rest as above 
end 
6

また#injectを使用してこれを行うことができます:

def using_resources(*resources, &block) 
    (resources.inject(block){ |inner,resource| proc { resource.run(&inner) } })[] 
end 

あなたはTHRのステップとして配列を使用すると、各リソースの前のProcの呼び出しを新しいProcにラップし、それを次のリソースに渡します。これにより、逆の順序でロックが取得されます(最後に指定されたリソースはロックされていません)。resources.reverse.inject ...