74
33

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 5 years have passed since last update.

RevertされたRuby 2.7の新機能メソッド参照演算子

Last updated at Posted at 2018-12-31

2019/11/12 Revertされたので使えなくなりました

👋

https://github.com/ruby/ruby/commit/fb6a489af2765a3b56e301adf0019af6bbad6156
https://bugs.ruby-lang.org/issues/16275

以下、deprecated

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

123.method(:to_s)
# => #<Method: Integer#to_s>

Methodオブジェクトとは

メソッドとレシーバーが対になったオブジェクトでProcと同じように呼び出せる。
https://docs.ruby-lang.org/ja/latest/class/Method.html

meth = 123.method(:to_s)
# => #<Method: Integer#to_s>
meth.call
# => "123"
meth.call(16)
# => "7b"

メソッド参照演算子

.:methodメソッドと同じようにメソッドをMethodオブジェクトとして取り出せる。

123.:to_s
# => #<Method: Integer#to_s>

methodメソッドが上書きされていても.:ならMethodオブジェクトを取り出せる

methodメソッドが上書きされていてもメソッド参照演算子はメソッドを取り出せる。べんり。

class Object
  def method(*)
    nil
  end
end

123.method(:to_s)
# => nil

123.:to_s.call
# => "123"

Refinementsで上書きされていても大丈夫

using Module.new {
  refine(Object) do
    def method(*); end
  end
}
method(:puts)
# => nil
self.:puts
# => #<Method: main.puts>

methodメソッド同様Refinementsで定義したメソッドは取り出せない

using Module.new {
  refine(Object) do
    def method(*); end
  end
}
self.:method.call(:puts).call(1)
# 1

単項演算子を取り出す場合

methodメソッド同様-@/+@のような形で取り出せる

1.method(:-@).call
# => -1
1.:-@.call
# => -1

べんりなのか

ブロックわたして何かする系のEnumerable的な処理書くときに便利そう。

[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種類、記号減ることもある。

74
33
1

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
74
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?