我想要做的是定义一个方法,该方法获取块中每个方法的结果(或调用块中的每个方法)并返回结果字符串......
例如:
def a_method(&block)
## build a string by calling each of the blocks methods
end
def brackets(str)
'('+str+')'
end
a_method do
brackets "foo"
brackets "bar"
end
# desired output => (foo)(bar)
我尝试将yield
放在a_method
中,但正如我所料,它只返回块中的最后一个评估表达式(在本例中为(bar)
)。
我已经了解了如何从块内的调用构建字符串,但找不到任何东西。我原以为这会是一种很常见的技术..有人可以解释一下吗?
答案 0 :(得分:2)
您可以使用DSL对象来处理此问题,从而为您提供更大的灵活性:
class StringBuilder
def method_missing(method, *args, &block)
@strings << (@original_self.send method, *args, &block)
end
def build(&block)
@strings = []
@original_self = eval "self", block.binding
instance_eval &block
@strings.join(' ') #format as you like
end
end
现在在需要的地方使用:
sb = StringBuilder.new
sb.build do
brackets "foo"
brackets "bar"
end
#=> (foo) (bar)
答案 1 :(得分:0)
["foo", "bar"].map(&method(:brackets)).join
更新如果您想使用各种方法的另一种方法:
def a_method(&block)
## build a string by calling each of the blocks methods
p block[].join
end
def brackets(str)
'('+str+')'
end
a_method do
[ brackets("foo"),
brackets("bar") ]
end
答案 2 :(得分:0)
如果您非常想要使用块来创建字符串,则必须使用巧妙的方法来记住它。其中一种方法是使用字符串实例并对其进行评估。
def a_method(&block)
"".instance_eval(&block)
end
def brackets(str)
self << "(#{str})"
end
str = a_method do
brackets "foo"
brackets "bar"
end
puts str
#=> (foo)(bar)