5 日ほど前に以下の PR がマージされました。
これまで型定義のテストとして gems/GEMNAME/VARSION/_scripts/test
を実行すると steep check
と rbs validate
が実行されていましたが、新たに bin/check-untyped-call.rb
も実行されるようになりました。CI でも同様に実行されます。
新しいテストが何をテストしているのかというと「untyped call
がないか?」です。untyped call
は steep stats
実行時に出力されるもので、これが 1 以上だと警告を出力するようです。
$ steep stats # Calculating stats: Target File Status Typed calls Untyped calls All calls Typed % ---------------------------------------------------------------------------- test test.rb success 3 5 8 37%
untyped call
がどういう条件で計上されるのかは Steep のコードを少し追ってもわからなかった(誰か教えてください…🙏)のですが、おそらく「untyped なレシーバーに対するメソッドコール」を計上しているのではないかと思います。
PR に記載されている例を抜粋すると
# rbs def f: () -> untyped # ruby f.something # <- untyped call
みたいなコードに対して警告を出します。なぜなら f
が untyped だからです。
f
が untyped だと(型上は)なんでも呼び出せてしまいます。たとえば f
が String だとして、以下のようなコードは明らかに間違っていますが従来のテストでは検知できません。
f.qawsedrftg
# rbs が正しく定義されていれば検知できる def f: () -> String # ruby f.qawsedrftg # <- NoMethod
ぼくも やってしまったことがあるのですが、せっかくテストコードを書いても意味がなくなってしまうため、自動で検知できるようにするため今回のテストが追加されたようです。今後はテストスクリプト実行時に untyped call
が steep stats
コマンドによって検知されると
5 method calls with untyped receiver detected from test.rb. Please assign the expected type to the receivers
といった警告が表示されるようになりました。