私は次のことを表現するためにある種の速記を使用したいと思います:
stuff.map {|x| puts x}
このようなものに:
stuff.map {puts}
構文がわかりません。誰かがこれを行う方法を教えてもらえますか?
まずmap
、マッピング操作を行っていないため、ここで使用するのは意味がありませんが、単純な副作用の反復です。それがまさにそのeach
目的です。使用するmap
ことは、将来のメンテナ(あなた自身を含む)にとって混乱を招くだけです。
each
そしてmap
ブロックを取ります。単項プレフィックス&
演算子を使用して、応答するオブジェクトをto_proc
ブロックに変換できます。ありがたいことに、Method
sはに応答するto_proc
ので、呼び出したいメソッドを直接渡すことができます。
stuff.each(&method(:puts))
ただし、がの場合stuff
はArray
、さらに簡単な方法があります。これは、puts
特殊なケースArray
で、実行していることを正確に実行できるためです。したがって、コードは100%同等です
puts stuff
あなたは配列を持っているので、あなたはただ書くことができます
puts stuff
ただし、一般に、文字列またはオブジェクトにメソッドを追加して、直接渡すことができます。メソッドがあるEnumerable.
ので、ブロックを必要とせずにそのメソッドを呼び出すことができます。Symbol
to_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))