2012-05-15 60 views
0

我有两种方法可能需要使用块调用某些代码。可选地调用红宝石块

选项1:

foo() 

选项2:

block_function do 
    foo() 
end 

如何将其中的两个之间在运行时切换?我真的不希望做到以下几点,因为foo()实际上是一大堆代码:

if condition then 
    foo() 
else 
    block_function do 
     foo() 
    end 
end 
+4

因此,将大量代码移入其自己的方法中,以便您勾画的选项不会令人难以接受? –

+0

或者如果foo使用一堆局部变量,则可以将foo定义为lambda。 – gmalette

+0

'block_function'是什么?或者你想打开带有和没有阻止的'foo'?你可以使用'block_given?'来检查一个块是否被赋予'foo'。 (如果是这样的话,我可以发表更详细的答案 – knut

回答

1
def condition_or_block_function 
    if condition 
    yield 
    else 
    block_function { yield } 
    end 
end 

condition_or_block_function do 
    foo() # which is really a lot of code :) 
end 

或者像其他人则建议,使foo()一串代码的实际方法,写你写在OP中。

更宽泛的版本为@tadman提示:

def condition_or_block condition, block_method, *args 
    if condition 
    yield 
    else 
    send(block_method, *args) { yield } 
    end 
end 

condition_or_block(some_condition, some_block_yielding_method) do 
    foo() # which is really a lot of code :) 
end 

@Christian Oudard添加注释指定特定的问题,可选装饰用DIV代码块做...结束与架桥机。这提示了另一种方法:

class BlockWrapper 
    def initialize(method=nil) 
    @method = method 
    end 
    def decorate 
    @method ? send(method) { yield } : yield 
    end 
end 

wrapper = BlockWrapper.new(condition ? nil : :div) 

wrapper.decorate do 
    #code block 
end 
+0

这可以通用化,以便在需要时调用方法名称。 – tadman

+0

@tadman好建议 – dbenhur