Ruby | 【衝撃】["d", "i", "c"].map(&:upcase) 一体この&:メソッドってナニナノ?【真相究明】


&:メソッドはなんかrubyのそういう省略した書き方ができるイディオムくらいの理解にとどまっていないかい🍓👮👊💘

["d", "i", "c"].map(&:upcase)

=> ["D", "I", "C"]

僕は、「&:」 と 「メソッド名」 でなんかそういう役割をしているものだと思っていまいた
ただしくは 「&」 と 「メソッド名(シンボル)」なんですね先生🏫 🙇♂️ ‍🏫 👨‍
* ぼきは DICの卒業生でつ

まず、Symbol#to_procを理解する

まず、リファレンス通り

:to_i.to_proc["ff", 16]  # => 255 ← "ff".to_i(16)と同じ

self に対応する Proc オブジェクトを返します。

生成される Proc オブジェクトを呼びだす(Proc#call)と、 Proc#callの第一引数をレシーバとして、 self という名前のメソッドを残りの引数を渡して呼びだします。

(っ◔◡◔)っ ♥ ちょっと日本語がむつかしい ♥

==> 解剖してみりゅ(☢🐒 お願いし松 🐤✎)

「self に対応する Proc オブジェクトを返します。」💢

シンボルに対してto_procを呼ぶとこういうProcオブジェクトが返るということ
(Symbol#to_procのSymbolは :メソッド を想定しています)

Proc.new{|obj, *args|, obj.send(self, *args)}

:to_iというselfに対応するProcオブジェクトとはこういうこと

:to_i.to_proc

==> Proc.new{|obj, *args| obj.send(:to_i, *args)}

「 Proc#callの第一引数をレシーバとして、 self という名前のメソッドを残りの引数を渡して呼びだします。」💢

proc = :to_i.to_proc
# Proc.new{|obj, *args| obj.send(:to_i, *args)}

proc.call("A", 16) # => 10

# 第一引数("A")をレシーバとして
#  self という名前のメソッド(:to_i)を
# 残りの引数(16)を渡して呼びだします。

# つまりこれと同じ
# "A".to_i(16)
# ==> "A"を16進数にする

ここで覚える大切なこと

Symbol#to_procはselfに対応したこのProcのオブジェクトを返す

Proc.new{|obj, *args|, obj.send(self, *args)}


< Side Note >

Symbol#to_proc => Symbolクラスのインスタンスメソッドto_procということ

クラス名#インスタンスメソッド
クラス名.クラスメソッド

rubyのドキュメントではこういう表記をしてい松💝💀

&:メソッド を発明(?)した人(中二病想定)の気持ちになってみる

もっと魔術を.....ッッ!!!!😈 🦹♂️👿‍

(1..5).reduce{|previous, current| previous + current }

中二病だからとりあえず黒魔術のsend使ってみるか🔮

(1..5).reduce{|previous, current| previous.send(:+, current) }

中二病だからブロックが必要なメソッドなのに引数としてブロック渡そwww

(1..5).reduce(&Proc.new{|previous, current| previous.send(:+, current) })

# Procオブジェクトをブロックに変換する&(アンパサンド)を前置きして
# 引数でProcオブジェクトをブロックとして渡す

アレwww この形どっかで見たことあるぞっっwwwww

Proc.new{|previous, current| previous.send(:+, current) }

完全に一致!!!!!!!

# 上記例のreduceの引数で渡しているProcオブジェクト
Proc.new{|previous, current| previous.send(:+, current) }

# to_procで返るProcオブジェクトの中身
Proc.new{|obj, *args|, obj.send(self, *args)}

じゃあ :+ に to_proc 呼べばいいんじゃね☬✞

(1..5).reduce(&:+.to_proc)

to_procも書かなくていいんだったらもっとかっこいいんだけどなぁ...

こんな感じに...

(1..5).reduce(&:+)

return ポチ

irb(main):666:0> (1..5).reduce(&:+)
=> 15

う、≋う≋ご≋い≋た≋あ≋あ≋あ≋あ≋あ≋!≋!≋!≋!≋

なぜか!!?

ブロックを受け取るメソッドにProc以外が渡されると、暗黙的に to_proc を呼び出して型変換を行う仕組みがあるため

暗黙的とか超カッケーじゃん....🤤🤤🤤🤤

まとめ

そういうこと

インスパイア(参考)

RubyのSymbol#to_procを考えた人になってみる