こんにちは、ふーが です。
この記事はぼくの勤務先である永和システムマネジメントで開催している ESM Advent Calendar 2022 の 4 日目の記事です。
さて、rbs のリポジトリを眺めていたら、README に使ったことのないコマンドがいくつも書いてあることに気が付きました。
$ rbs version
$ rbs list
$ rbs ancestors ::Object
$ rbs methods ::Object
$ rbs method Object then
とても今更ですがそれぞれどんなコマンドなのか見てみます。
rbs のバージョンは 2.8.1 で試します。
$ rbs -v rbs 2.8.1
rbs version
実行結果:
$ rbs version rbs 2.8.1
これはそのまんまですね。バージョン番号が出力されます。
RBS::CLI#run
に定義されていて、実装はこのあたりです。
github.com
rbs list
実行結果:
$ rbs list ::Array (class) ::BasicObject (class) ::Binding (class) ::Class (class) ::Comparable (module) ::Complex (class) ::Dir (class) . . (略)
型定義されている Class, Module, Interface が出力されます。
引数として --class
のように指定ができて、指定されたもののみ出力されるようにできます。
例えば以下なら、型定義のうち Class と Module のみ出力されるようにする、といった具合です。
# Interface は出力されない $ rbs list --class --module
rbs ancestors
実行結果:
$ rbs ancestors ::Object ::Object ::Kernel ::BasicObject
引数で指定した Class, Module の(自身を含む)祖先が出力されます。
オプションとして --singleton
, --instance
があり、デフォルトでは --instance
を指定したことになります。 --singleton
を指定すると singleton クラスを含んだ結果が出力されます。
$ rbs ancestors --singleton ::Object singleton(::Object) singleton(::BasicObject) ::Class ::Module ::Object ::Kernel ::BasicObject
実装はこの辺からです。 github.com
rbs methods
実行結果:
$ rbs methods ::Object ! (public) != (public) !~ (public) <=> (public) == (public) === (public) =~ (public) Array (private) . . (略)
引数で指定した Class, Module のメソッドの一覧を可視性付きで出力します。
オプションの --instance
と --singleton
については rbs ancestors
コマンドと同じ意味合いのようですが、こちらのコマンドには --inherit
, --no-inherit
というオプションもあります。
--inherit
オプションは super class や mix-in した Module で定義されているメソッドについても出力します。これはデフォルトの動作です。
--no-inherit
オプションはその逆で、それらのメソッドについては出力しません。
実装はこの辺からです。 github.com
rbs method
実行結果:
$ rbs method String to_i ::String#to_i defined_in: ::String implementation: ::String accessibility: public types: (?::int base) -> ::Integer
第一引数に Class (Module)、第二引数にメソッド名を渡すことで、そのメソッドの型定義情報が出力されます。定義元や可視性、型情報などが出力されています。
こちらもオプションは --instance
と --singleton
があり、--instance
がデフォルトです。
実装はこの辺からです。 github.com
おわりに
クラスやメソッドの型定義を出力できるコマンド類があることを知り「これを使って型と実装の乖離を検知できたりしないかな」と思ったのですが、実装を読んでみると標準ライブラリと gem の型定義のみを読み込んで出力しているようでした(たぶん。違ったら教えてください)。つまり自分で定義した sig/
以下にあるような型定義は対象外っぽい…。
COMMANDS の配列 を見る限り他にもまだコマンドがあるようなので、折を見てそちらもどんなコマンドなのかを追ってみたいと思います。