はじめに
RubyKaigi2023 1日目に参加しました!さまざまな発表がありましたが、特に僕がすごいと思ったセッションを紹介します!!
本記事は RubyKaigi 1日目のセッションの1つである、@tompng
さんによる発表 「Power up your REPL life with types」の概要とその中で出てきた katakata_irb
gem を試しに使ってみた記事です。
セッション概要
発表のタイトルは「Power up your REPL life with types」です!タイトルの通り、型(RBS)でREPL(IRB) をパワーアップさせる、という発表です。
IRBの現状
ruby を対話形式で実行できる irb ですが、現状でも以下のように補完してくれます。(配列のメソッドが候補に出てきます。)
上記の例では結構いい感じの補完候補が出ていそうです。しかし、正規表現で実装されているため場合によっては誤った候補が出たり、メソッドチェーンの場合の補完の候補が微妙だったりします。
そこで、型の情報を使っていい感じに補完ができたらいいよね?と言うことで発表者の @tompng
さんが実装したのが katakata_irb
gem です!すごい!!
katakata_irb
gem
gem の名前は「型」と「カタカタ(擬音)」が由来しているらしいです。
katakata_irb
が型の情報を使っていい感じに補完する仕組みを簡単に説明します。
- 不完全なコードから、構文木を作成し
- irb 自体がインデントの深さなどの情報を持っているので、その情報を使って足りないカッコや
end
などを補完します。 - 補完したコードを Ripper でパースし構文木が得られます。
- irb 自体がインデントの深さなどの情報を持っているので、その情報を使って足りないカッコや
- RBSでメソッドチェーンを評価
- 構文木の種類に応じて、カーソルの位置にはどんな型が来るのかをパターンマッチして求めます。
- 型がわかるので、適切な補完候補が得られます。
- IRBの補完を上書きする
- 型情報から補完候補が得られたので、IRBの補完を上書きします。
このような流れで、メソッドチェーンの場合も適切な補完候補が得られるようです。なんと、上記の実装が約150行で実装できているらしいです!
さらに、もっと強力な補完がしていですよね?ということで、以下も実現されているらしいです!
- 変数のスコープや、if の結果に応じて型が変わる場合も適切な型から補完候補が得られる
- each や map など、ブロック内の変数も、型変数を考慮して適切な候補が表示される
- sig ディレクトリやrbs_collection.taml による型情報が仕様される
実際に使ってみた
使い方は、 katakata_irb
をインストールして、irb上で require するだけです!
λ irb
irb(main):001:0> require "katakata_irb"
=> true
メソッドチェーン
katakata_irb
を使わない場合
n.abs
は Integer
ですが、以下のように、Integer 以外のメソッドも表示されてしまっています。
katakata_irb
を使った場合
n.abs
が Integer
型と判定され、 Integer
のメソッドのみ表示されています!!
if の条件によって型が変わる場合
以下のように、if の結果によって Integer
や String
になる場合はどうなるでしょうか?
Proc.new do
a = 1
if a > 0
a = "hoge"
end
a. <- ここを補完する
katakata_irb
を使わない場合
先ほどと同様に、適切な候補を出すことができていません...
katakata_irb
を使った場合
String
のメソッド ascii_only?
や Integer
のメソッド abs
が表示されています!!!
さいごに
やはり型の力は偉大です!Rubyが型でこれからもっと便利になっていってほしいですね!
発表者の @tompng
さん本人による以下の記事も読みましょう!!