动态嵌套红宝石块

bvk*_*bvk 5 ruby

想象一下,我有一些带有run方法的资源对象,它在为该资源持有的锁下执行block参数.例如,像这样:

r = Resource("/tmp/foo")
r.run { ... }
Run Code Online (Sandbox Code Playgroud)

如何编写一个ruby方法,它接受一个资源数组并在为所有资源保持的锁下执行其block参数,例如:

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

    yield;

  end; end; end; ...
end
Run Code Online (Sandbox Code Playgroud)

有可能吗?

Sen*_*Uka 9

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

这是代码:

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
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

using_resources Resource.new('/tmp'), Resource.new('http://stackoverflow.com') do
  do_some_processing
end
Run Code Online (Sandbox Code Playgroud)

你说,"这需要一系列资源." 如果你Array已经并且需要使用它,你可以在Array外面打电话:

 using_resources *my_array do
   do_some_processing
 end
Run Code Online (Sandbox Code Playgroud)

或者在方法定义中,允许您使用s ArrayResources 列表来调用它:

def using_resources(*res, &block)
  res = [*res]
  # rest as above
end
Run Code Online (Sandbox Code Playgroud)


ram*_*ion 7

你也可以这样做#inject:

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

在单步执行数组时,将每个资源的前一个Proc的调用包装在新的Proc中,然后将其传递给下一个资源.这会以相反的顺序获取锁定(给出的最后一个资源是第一个解锁的资源),但是可以通过使用来改变resources.reverse.inject ...