私は次のことを表現するためにある種の速記を使用したいと思います:
stuff.map {|x| puts x}
このようなものに:
stuff.map {puts}
構文がわかりません。誰かがこれを行う方法を教えてもらえますか?
まずmap、マッピング操作を行っていないため、ここで使用するのは意味がありませんが、単純な副作用の反復です。それがまさにそのeach目的です。使用するmapことは、将来のメンテナ(あなた自身を含む)にとって混乱を招くだけです。
eachそしてmapブロックを取ります。単項プレフィックス&演算子を使用して、応答するオブジェクトをto_procブロックに変換できます。ありがたいことに、Methodsはに応答するto_procので、呼び出したいメソッドを直接渡すことができます。
stuff.each(&method(:puts))
ただし、がの場合stuffはArray、さらに簡単な方法があります。これは、puts特殊なケースArrayで、実行していることを正確に実行できるためです。したがって、コードは100%同等です
puts stuff
あなたは配列を持っているので、あなたはただ書くことができます
puts stuff
ただし、一般に、文字列またはオブジェクトにメソッドを追加して、直接渡すことができます。メソッドがあるEnumerable.ので、ブロックを必要とせずにそのメソッドを呼び出すことができます。Symbolto_proc
class Object; def myputs; puts self; nil; end; end
stuff.each &:myputs # or, even better, ...
stuff.myputs
map(&:method)構文を暗示しているかもしれませんが、 puts'の場合は不可能です。
内部的には、Rubyはto_procシンボルを呼び出します。このメソッドの本体は次のとおりです。
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
あなたの場合、objはstuffであり、selfはputsです。
ご存知stuffのように、メソッドに応答しないためputs、現在の式でシンボル構造を使用することはできません。
Array#mapのブロック形式は配列を返すため、各要素を標準出力に送信するには、レシーバー( Kernel#putsを使用するKernelなど)が必要です。あなたはこのようなことをすることができます:
puts [1, 2, 3].map(&:to_s)
しかし、それは確かに物事を短くしたり、より明確にしたりするものではありません。おそらく、あなたは本当に達成しようとしていることが何であるかを再考する必要があります。
すでに閉鎖されていますが、私は提案します:
stuff.map(&Kernel.method(:puts))