假设我有with_foo
一个需要一个块的函数,并将它包裹在一段代码中,比如
with_foo do
puts "hello!"
end
现在我想让包装有条件,比如
if do_with_foo?
with_foo do
puts "hello!"
end
else
puts "hello!" # without foo
end
有什么方法可以写得更短/更优雅,这意味着无需重复代码puts "hello!"
?
假设我有with_foo
一个需要一个块的函数,并将它包裹在一段代码中,比如
with_foo do
puts "hello!"
end
现在我想让包装有条件,比如
if do_with_foo?
with_foo do
puts "hello!"
end
else
puts "hello!" # without foo
end
有什么方法可以写得更短/更优雅,这意味着无需重复代码puts "hello!"
?
如果您愿意用块指定参数,这是可能的。
上面给出with foo
的,你可以写这样的片段:
whatever = proc {puts "hello"}
#build a proc object with a block
if do_with_foo?
with_foo &whatever
#pass it to with_foo
else
whatever.call
#normally call it
end
使用代理模式的概念证明:
class BlockWrapper
def initialize(obj, use_wrapper)
@obj = obj
@use_wrapper = use_wrapper
end
def method_missing(*args, &block)
@use_wrapper ? @obj.send(*args, &block) : block.call
end
end
module Kernel
def wrap_if(use_wrapper)
BlockWrapper.new(self, use_wrapper)
end
end
def with_foo
puts "with_foo: start"
yield
puts "with_foo: end"
end
wrap_if(true).with_foo do
puts "hello!"
end
wrap_if(false).with_foo do
puts "hello, no with_foo here!"
end
输出:
with_foo: start
hello!
with_foo: end
hello, no with_foo here!
我认为你可以这样做:
def without_foo &pr
pr.call
end
send(do_with_foo?? "with_foo" : "without_foo") do
puts "hello!"
end
您可以将复制代码放入Proc
对象中并将其作为块传递给方法或直接调用它。
hello = proc { puts 'hello' }
with_foo(&hello)
# OR
hello.call
def simple_yielder
yield
end
def maybe_with condition, with_method
send( condition ? with_method : :simple_yielder ) { yield }
end
#...
maybe_with( do_with_foo?, :with_foo ) do
puts "Hello?"
end