No day younger than today

RubyとかRailsとか蒙古タンメンとか

gem_rbs_collection に新たなテストが追加された

5 日ほど前に以下の PR がマージされました。

github.com

これまで型定義のテストとして gems/GEMNAME/VARSION/_scripts/test を実行すると steep checkrbs validate が実行されていましたが、新たに bin/check-untyped-call.rb も実行されるようになりました。CI でも同様に実行されます。

新しいテストが何をテストしているのかというと「untyped call がないか?」です。untyped callsteep 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 callsteep stats コマンドによって検知されると

5 method calls with untyped receiver detected from test.rb. Please assign the expected type to the receivers

といった警告が表示されるようになりました。