Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
33
Help us understand the problem. What is going on with this article?
@hanachin_

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

More than 1 year has passed since last update.

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

33
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
hanachin_
既婚バイ
codetakt
学習管理システム「schoolTakt」を運営するEdTechのスタートアップ企業

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
33
Help us understand the problem. What is going on with this article?