QA@IT

Rubyのmap(&:name)というのはどういう意味?

6923 PV

mapを使っているコードで、

    def split_and_normalize_names(names)
      names.to_s.downcase.split(',').map(&:strip).uniq
    end

というのを見かけました。この場合のmap(&:strip)というのはどういう意味で何をやっているのでしょうか?

回答

「配列の各要素について前後の空白を取り除いた新たな配列を返す」の意味で、冗長に書き直すと以下のようになります。

names.to_s.downcase.split(',').map {|i| i.strip }.uniq

長い説明:

ブロック付きのメソッドを呼び出す際、ブロックの代わりに Proc オブジェクトを渡すことができます。この場合、Proc オブジェクトに & 記号を前置します。

p = proc {|i| i.upcase }
%w(foo bar).map(&p) # %w(foo bar).map {|i| i.upcase } と同じ

Symbol#to_proc というメソッドがあります。これはレシーバに対してシンボルと同名のメソッドを呼び出す Proc オブジェクトを返すメソッドです。言葉で説明するとわかりにくいですが、つまりこんな感じです。

:upcase.to_proc #=> proc {|i| i.upcase }

この2つを組み合わせるとこう書けるようになります。

%w(foo bar).map(&:upcase.to_proc)

& を前置すると自動的に to_proc が呼ばれますので、さらに縮めてこう書けます。

%w(foo bar).map(&:upcase)

この記法はブロック付きメソッド呼び出しをシンプルに記述するため、主に Rails 界隈で使われるイディオムです。

編集 履歴 (2)
ウォッチ

この質問への回答やコメントをメールでお知らせします。