[Sorbet] テストを実行するだけで型(sig)を書いてくれるツール「gelauto」の紹介
背景
RubyのプロジェクトにSorbetで型をあてているとき、メソッドの型を何も書かないとuntypedになってしまいます。
とはいえ、すべてのメソッドにsigで書いていくのは結構大変ですよね。
実は、Sorbetにはsigを提案してくれる機能があります。
しかし、個人的な印象として、型がある程度あたったコードでないとuntypedと提案されることが多いように思います😇
紹介
今回紹介するgelautoは、テストを実行するだけで型を書いてくれるツールとなっています。内部的にはTracePointを使っています。
テストはあるけど、まだあまり型があたっていないプロジェクトには特に便利なツールと言えそうです。
Sorbet(ソルベ)に合わせて、gelato(ジェラート)をもじった名前にしてあるのもいいですね。
gelautoの読み方もジェラートでいいのでしょうか。
類似のツールとして、テストを実行するとRBSで型を書いてくれるRBS::Traceがあります。
最近、SorbetがRBS Commentに対応し始めたので、これらを組み合わせて使うのもありかと思います。
今年のRubyKaigiでは、RBS::TraceとSorbetのRBS Comment対応の両方の話が聞けそうですね👀
- Automatically generating types by running tests
- Inline RBS comments for seamless type checking with Sorbet
使い方
ではミニマルな環境を作り、実際にgelautoを使ってみます。(gelauto v2.1.0)
コードはこちらに: https://github.com/pvcresin/minimal-gelauto-sample
今回はBundlerを使ったサンプルを作りました。
Gemfileは以下のようになっています。
# frozen_string_literal: true
source "https://rubygems.org"
gem "gelauto"
gem "racc"
gem "rspec"
gem "sorbet-static-and-runtime"
Sorbetで型チェックを行い、RSpecでテストを書いています。gelautoの実行にraccがいるようだったので、加えています。(追記: raccの追加はgelauto v2.2.0でいらなくなりました。)
gelautoはいろいろな使い方ができるのですが、このサンプルではRSpecを実行したときにテスト対象のコードに型(sig)を追記する形にしています。
例えば、以下のようなlib/sample.rbに対し、
# typed: true
require 'sorbet-runtime'
class A
extend T::Sig
def foo(x)
x.to_s
end
end
RSpecで書かれたテスト、spec/sample_spec.rbがあるとします。
require_relative '../lib/sample'
describe 'A' do
describe "#foo" do
it "returns the string" do
expect(A.new.foo(1)).to eq('1')
end
end
end
ここでgelautoのREADME.mdに従って以下のコマンドを実行します。
bundle exec gelauto run --annotate $(find . -name '*.rb') -- bundle exec rspec spec/
するとlib/sample.rbにsigが追加されました🎉
# typed: true
require 'sorbet-runtime'
class A
extend T::Sig
+ sig { params(x: Integer).returns(String) }
def foo(x)
x.to_s
end
end
手軽で良いですね。
気になる点
最強かと思いきや気になる点もあります。
- 開発はあまり活発ではない😇
- 最後のリリースではparserが2系なので
def a = 1
などが使えない- parserを3系にあげるコミットはあるので、リリースされれば解決するか
- (追記: gelauto v2.2.0でParserが3系になり、解消されました。)
- 末尾の改行が消される
期待と不安を同時に味わえるgelauto。
どんどんユーザが増えることによって、盛り上がっていくといいですね。
追記
2025/04/04
gelauto v2.2.0がリリースされ、以下の点が解消されました🎉
- Bundlerでgelautoを実行する際に別途raccのインストールが必要
- 最後のリリースではparserが2系なので
def a = 1
などが使えない
Sampleのバージョンも更新してあります。
Discussion