1

我想要做的是定义一个方法来获取块中每个方法的结果(或调用块中的每个方法)并返回结果字符串......

例如:

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))。

我已经查看了如何从块内的调用构建字符串,但找不到任何东西。我原以为这将是一种相当普遍的技术..有人可以解释一下吗?

4

3 回答 3

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)
于 2012-05-15T19:00:22.513 回答
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)
于 2012-05-15T18:45:11.760 回答
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
于 2012-05-15T18:34:32.817 回答