1. khsk
Changes in body
Source | HTML | Preview
@@ -1,124 +1,124 @@
`method`メソッドを短く書けるメソッド参照演算子の紹介です。
https://bugs.ruby-lang.org/issues/12125
https://github.com/ruby/ruby/commit/67c574736912003c377218153f9d3b9c0c96a17b
## `method`メソッドとは
メソッドを`Method`オブジェクトとして取り出せるべんりメソッド
https://docs.ruby-lang.org/ja/latest/method/Object/i/method.html
```rb
123.method(:to_s)
# => #<Method: Integer#to_s>
```
## `Method`オブジェクトとは
メソッドとレシーバーが対になったオブジェクトで`Proc`と同じように呼び出せる。
https://docs.ruby-lang.org/ja/latest/class/Method.html
```rb
meth = 123.method(:to_s)
# => #<Method: Integer#to_s>
meth.call
# => "123"
meth.call(16)
# => "7b"
```
## メソッド参照演算子
`.:`で`method`メソッドと同じようにメソッドを`Method`オブジェクトとして取り出せる。
```rb
123.:to_s
# => #<Method: Integer#to_s>
```
## `method`メソッドが上書きされていても`.:`なら`Method`オブジェクトを取り出せる
`method`メソッドが上書きされていてもメソッド参照演算子はメソッドを取り出せる。べんり。
```rb
class Object
def method(*)
nil
end
end
123.method(:to_s)
# => nil
123.:to_s.call
# => "123"
```
Refinementsで上書きされていても大丈夫
```rb
using Module.new {
refine(Object) do
def method(*); end
end
}
method(:puts)
# => nil
self.:puts
# => #<Method: main.puts>
```
`method`メソッド同様Refinementsで定義したメソッドは取り出せない
```rb
using Module.new {
refine(Object) do
def method(*); end
end
}
self.:method.call(:puts).call(1)
# 1
```
## 単項演算子を取り出す場合
-`method`メソッド同様`-@`/`+@`のような形で取り出せる
+`method`メソッド同様`-@`/`+@`のような形で取り出せる
```rb
1.method(:-@).call
# => -1
1.:-@.call
# => -1
```
## べんりなのか
ブロックわたして何かする系の`Enumerable`的な処理書くときに便利そう。
```rb
[1,2,3].map(&2.:*)
# => [2, 4, 6]
["エロ"].any?(&"イエロー".:include?)
# => true
require "prime"
(1..10).select(&Prime.:prime?)
# => [2, 3, 5, 7]
```
## まとめ
trunkのrubyを入れるとすぐに`.:`を使えるのでべんりです。
## 2019/03/08 追記
よくある反応についての感想です。
### `.:`違和感ある
他言語ではメソッド呼び出しで`()`が必要だから`()`なしで参照が取れたりするけどRubyでは`()`省略できるのでそれではダメそう。
メソッド呼び出しの`.`の後ろに`:`1文字つけくわえるだけ、通常のメソッド呼び出しより1文字多いだけで参照とれるのはそこまで違和感がない気持ち。
### 記号多い
実際`{|x| y.foo(x) }`は記号6種類ぐらい使っているので`(&y.:foo)`は記号5種類、記号減ることもある。