2009-07-29 67 views
4

想象一下,我有一些资源对象的run方法,该方法在为该资源保存的锁下执行block参数。例如,像这样:红宝石块的动态嵌套

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

我如何写一个Ruby方法,这需要一系列资源,并执行其块参数的所有资源持有锁下,如:

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

    yield; 

    end; end; end; ... 
end 

是它可能呢?

回答

8

在我看来,这是最好的使用递归

这里做的是代码:

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 

并使用它像这样:

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

你说,“这需要一系列资源。“如果你有一个Array已经和需要使用它,您可以图示的Array外呼:

using_resources *my_array do 
    do_some_processing 
end 

或者方法的定义,它允许你要么被ArrayResource列表调用它里面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 ...