183
127

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Ruby】array.map(&:method)を理解する

Last updated at Posted at 2019-01-30

概要

Rubyで書かれたコードを見ていると度々array.map(&:メソッド名)の形式のイディオムを見かけると思います。そこで、array.map(&:メソッド名)がどのような動きをし、またなぜそのような動きをするのかまとめました。

何をする?

簡単にいうと以下のように配列の要素1つ1つに(&:メソッド名) で与えられたメソッドを呼んでいます。
(以下の例では文字列のabに対してString#upcaseメソッドを呼んでいます。

['a' ,'b'].map(&:upcase) #=> ["A", "B"]

なぜこのような結果になる?

引数にある&

まず、Rubyが引数内で&を見つけるとその値をプロック(proc)として扱おうとし、その値(この場合:upcase)に対してto_procメソッドを呼びます。

class Symbol
  def to_proc
    puts "to_procが呼ばれました!"
  end
end

p [].map(&:upcase) #=> to_procが呼ばれました!
## その後TypeErrorが発生。

Symbol#to_procメソッドとは?

to_procメソッドはその名の通り、渡されたシンボルを手続きオブジェクトのprocとして返すものです。

prc = :upcase.to_proc 
p prc #=> #<Proc:0x00007f99d303e458(&:upcase)>

作成したprcを文字列に呼んでみます。

p prc.call("string") #=> STRING

まとめると以下の事を行なっています。

:upcase.to_proc.call("string")#=> STRING

結論

つまり、array.map(&:メソッド名)(&:メソッド名)部分は:メソッド名.to_proc.callを省略した形という事になります。
以下の例で実際に両者の比較をみてみます。

# array.map(&:メソッド名)の記法
['a','b'].map(&:upcase) #=> ["A", "B"]

# 省略しない記法
['a','b'].map do |string|
  :upcase.to_proc.call(string)
end
#=> ["A", "B"]

参考

Understanding Ruby's idiom: array.map(&:method)
https://therealadam.com/2008/05/01/beautiful-multi-line-blocks-in-ruby/

183
127
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
183
127

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?