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
["foo", "bar"].map(&method(:brackets)).join

UPDATEさまざまな方法を使用する場合の別の方法:

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 に答える
0

ブロックを厳密に使用して文字列を作成したい場合は、それを覚える賢い方法を使用する必要があります。これらの方法の 1 つは、文字列インスタンスを使用して、そのブロックを評価することです。

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 に答える