katakata_irb を導入してみた


2023年 05月 16日

こんにちは、@tk0miya です。RubyKaigi 2023、楽しかったですね。

今回は RubyKaigi 2023 で最も感銘を受けた gem である、katakata_irb を導入してみたので、レポートしてみたいと思います。

katakata_irb とは?

これまでも irb には入力補完機能がありましたが、サジェストされるメソッドが不完全であったり、メソッドチェーンの呼び出しで補完が動かないといった問題がありました。

katakata_irb gem は Ruby の型定義情報を使って irb の補完機能を強化するための gem です。
RubyKaigi 2023 の Power up your REPL life with types – RubyKaigi 2023 というセッションで紹介されました。

katakata_irb gem はその名の通り irb を強化するための gem ですが、irb は多くのところで使われているので、思わぬところにも効果があります。
たとえば、rails console は内部的に irb を利用しているので、katakata_irb gem を導入すると rails console の入力補完機能も強化されます。また、デバッグに binding.irb をつかっている人も同様にデバッグコンソールの強化に繋がります。

普段 irb を使う機会はないや…と思っている人も試してみる価値はあります。

これまでの補完

比較のために、これまでの irb の補完の様子を見てみましょう。
たとえば 123 という数値を入れてメソッドを呼び出そうとすると以下のようにサジェストが行われます。
このケースではうまく行っているように見えるのですが、他のオブジェクトではサジェストがされなかったり、誤ったりすることがあります。

また、今度はメソッドチェーンでどうなるか見てみましょう。
123.to_s に対してさらにメソッド呼び出しを試みます。String 型に対するメソッド呼び出しとなるのですが、irb はうまくサジェストしてくれません。

katakata_irb による補完:

それでは、katakata_irb を入れるとどうなるのかを見てみましょう。
先程と同様に 123 に対するサジェストは以下のようになります。
サジェスト候補の右側を見ると、Integer と表示されていますが、これは katakata_irb がオブジェクトの型を認識してサジェスト候補を出しているという表示です。

また、メソッドチェーン呼び出しでは以下のように入力補完をしてくれます。
123.to_s が String 型を返すというのを認識しているので、オブジェクトの方は String 型と識別されていますし、サジェストされるメソッドも String のメソッドです。

もう少し複雑な例として、ブロックを試してみました。
ここも意図通りオブジェクトの型が識別されて、適切なサジェストが行われています。

インストール方法

katakata_irb gem の動作を理解したところで、あらためてインストール手順を確認しましょう。

  1. katakata_irb gem をインストールする
  2. .irbrc にロードする設定を書く

katakata_irb gem のインストールはシンプルですね。いつもどおり Gemfile に記述するか、gem install してください。

group :development do
  gem 'katakata_irb', require: false
end

次に、 .irbrc ファイルに設定を加えます。.irbrcirb の設定ファイルです
自分のホームディレクトリもしくはプロジェクトルートに配置するとよいでしょう。
以下の内容を .irbrc に書きます。

require 'katakata_irb' rescue nil

使ってみる

特別な手順はありません。irb コマンドや rails console コマンド経由で irb を起動してください。
いろいろ入力してみて、いい感じにサジェストされるか実験してみてください。

カスタムの型定義を用意する

さて、ここまでは katakata_irb が提供してくれるデフォルトの型定義情報に基づいてサジェストしていました。
実際の Ruby プロジェクトでは、3rd party gem を使ったり、自身でクラスを定義して使いますよね。
こうしたクラス群については、型情報を持たないため katakata_irb は入力補完を受けることができません。

より広範囲な入力補完を受けるために、さらに設定を追加します。

3rd party gem の型情報を取得する

3rd party gem については、gem_rbs_collection というリポジトリにさまざまな gem の型定義情報が集約されています。
このリポジトリは Ruby コミュニティの有志により情報が収集されているものです。
型情報が収録されている gem の数はまだあまり多くはありませんが、ActiveRecord や ActiveSupport といったよく使われている gem については型定義情報が提供されているので、まずはこれらの型定義をインストールしましょう。

インストールする

まずは設定ファイルを生成します。

bundle exec rbs collection init

上記のコマンドを実行すると rbs_collection.yml というファイルが生成されます。

次に、以下のコマンドを実行して gem_rbs_collection リポジトリから型定義を取得します。

bundle exec rbs collection install

上記のコマンドを実行すると、rbs_collection.lock.yml というファイルと .rbs_collection/ というディレクトリが生成されます。

 

rbs_collection.ymlrbs_collection.lock.yml にはリポジトリからダウンロードする型定義情報の設定と、実際にダウンロードした型定義情報の一覧が記載されています。
Gemfile/Gemfile.lock と同様の関係にあるファイルです。コミットして管理すると良いでしょう。

.rbs_collection/ ディレクトリには実際にダウンロードした型情報が保存されています。
こちらは、コミットする必要はないものですので、 .gitignore に追加してコミット対象から外すとよさそうです。

実際にプロジェクトで利用する場合は

  • 最初にだれかが rbs_collection.ymlrbs_collection.lock.yml を生成する
  • 生成したファイルをソースコードにマージする
  • 各メンバーの手元では、rbs collection install を実行する

という流れで、各メンバーの開発環境に型定義ファイルをダウンロードします。

使ってみる

型定義ファイルをダウンロードしたら、あとは  irb を起動するだけで、入力補完に型定義が利用されます。
たとえば、ActiveSupport の型定義をダウンロードされると、以下のように入力補完が行われます。

Rails アプリケーションから型定義を抽出する

あとは開発対象のアプリケーションの型定義情報を用意できると、より便利そうですよね。
Rails アプリケーションの場合には便利 gem が存在します。
rbs_rails gem は DB スキーマやモデル定義(associationなど)などから型定義を自動抽出してくれます。

インストールする

まずは Gemfile に rbs_rails を追加し、 bundle install を実行します。

group :development do
  gem 'rbs_rails'
end
bundle install

次に rbs_rails 用の Rake タスクを生成します。生成用の Rake タスクが用意されています。

bundle exec rails g rbs_rails:install

最後に rbs_rails:all タスクを実行します。

bundle exec rails rbs_rails:all

一連のコマンドを実行すると、Rails アプリケーションから抽出された型定義が sig/rbs_rails ディレクトリ以下に出力されます。

使ってみる

これまでと同様に irb を起動します。

たとえば、以下は ActiveRecord モデル Staff に対する入力補完が行われている様子です。
Staffモデルが認識されており、AR 系のメソッドが提供されている様子が見えます。

また、こちらは association に基づいて関連モデルのサジェストをしている様子です。

この例では StaffCorporationに belongs_to しているので、たどることができています。

型定義ファイルを維持する

DB スキーマの変更やモデルの定義が変更されるにつれ、抽出した型定義は古くなっていきます。
自動抽出した型定義ファイルは rbs_rails:all で更新できるため、定期的に (書き換える都度に) 型定義ファイルを再生成することで、入力補完の精度を維持できます。

GitHub Actions などで自動化すると便利そうですが、それはまた別の記事で紹介したいと思います。

型定義ファイルを書く

ここまでは gem_rbs_collection や rbs_rails gem で型定義情報をお手軽に得られる方法を説明しました。
入力補完の精度をより上げるには、自分で作ったクラスやメソッドの型情報を定義していく必要があります。

これらについては、我々も知見が不足しているので、調査の上あらためて紹介したいと思います。

まとめ

この記事では katakata_irb を使った irb の入力補完機能の強化方法を紹介しました。

katakata_irb はかんたんに導入できて、とても効果のある gem です。RubyKaigi でトークを聞いて「帰ったらすぐに入れてみよう」と思える素晴らしい gem だと思います。

 

今回は katakata_irb gem を中心に紹介しましたが、今回セットアップした型定義情報は他のツールでも利用できます。

  • IDE の入力支援 (ポップアップヒント、入力補完)
    • VSCode, Vim などなど
  • ソースコードの静的解析 (型チェック)

型定義情報をうまく利用すると開発効率を上げ、ミスやエラーをへらすことに繋がるので、導入する価値がありそうです。

今回紹介した範囲については、いくつかの設定で済むため、導入障壁もかなり低いと感じています。利便性も非常に高いので、普段の開発に徐々に型を入れていくというのを検討してみてはいかがでしょうか。