简体   繁体   中英

Optionally calling a block in ruby

I have two ways I might need to call some code using a block.

Option 1:

foo()

Option 2:

block_function do 
  foo()
end

How do I switch between the two of these at runtime? I really don't want to do the following, because foo() is actually a whole lot of code:

if condition then
    foo()
else
    block_function do 
      foo()
    end
end
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

Or as others suggested, make the foo() bunch of code an actual method and write what you wrote in the OP.

More generic version as @tadman suggests:

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 added a comment specifying the specific problem, optionally decorating a code block with div do...end with Erector. This suggests another approach:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM