はじめに
イタンジ株式会社の稲垣です。ノマドクラウドという不動産仲介向けのSaaSを開発しています。 趣味はFF14で本当はFF14の記事を書こうと思ったのですが、つい先日gemを作るというネタになることをしてしまったので作ったgemについて書きます。
作ったもの
これなに
rubyファイルのコメントに型情報を書くことで、rbsファイルを生成することができるgemです。
例えばこんなrubyコードを書いて
# example.rb module App # @sig (Integer) -> String def some_method(arg) arg.to_s end private # @sig (String) -> Integer def some_private_method(arg) arg.to_i end end
こんなコマンドを叩くと
irbs example.rb -o example.rbs
こんなrbsファイルが生成されます。
# example.rbs module ::App public def some_method: (Integer) -> String private def some_private_method: (String) -> Integer end
RBSについて
「こんなrbsファイル」と言われてもrbsって何?と思う方も多いと思います。 なのでまずrbsについて簡単にですが説明します。
最近のRubyは型を取り扱うことができるようになりました。
rbsとはRuby 3.0から標準添付されるようになった、rubyの型情報を扱う言語(とそれらを扱うrbs
cliコマンド)のことです。
ちょっとややこしいのですが、rbsはrbとは独立して存在しており、それ自体はrubyの動作に影響を及ぼすことはありません。 あくまで型情報を記しているだけで、実際に型検査を行うためには別のツールが必要になります。
現状ではSteepがrbsを用いた実用的な唯一の型検査ツールです。
Rubyで型を使う開発フローをざっくり書くと、
- rbを書く
- 1の型情報のrbsを書く
- Steepでrbsを使ってrbの静的な型検査を行う
のようになります。
gemの話にもどると、irbsは上記開発フローの2. 1の型情報のrbsを書く
を補助するツールと位置づけることができます。
Rubyの型周りについての包括的な説明はクックパッド開発者ブログ様の以下の記事が詳しいので、一読をおすすめします。 techlife.cookpad.com
また、弊社blogでも実際にrbsを活用した記事があるので、併せてご覧いただければと思います。 tech.itandi.co.jp
irbs
上述の通り、Rubyで型を用いた開発を行うためにはrbsファイルを作成する必要があります。 ただこれ実際にrbsファイルを手書き1するとわかるのですが、rbとrbsを行ったり来たりが非常にめんどうくさいです。 なので、rbファイルにインラインでrbsを書けるようにしました。2
記法
@sig
メソッド定義の上のコメントに、@sig
に続けてメソッドに対する型注釈を書くと、そのメソッドに対するrbsコードが出力されます。
# @sig () -> void def some_method; end
public def some_method: () -> void
メソッド名と、視認性(public|private
)は自動的に補完されます。
型注釈については補完されることなく(たとえrbsとして間違っていたとしても)そのまま反映されます。
attr_*
メソッドに対しても型注釈を書くことができます。
# @sig String attr_accessor :foo
public attr_accessor foo: String
特殊なケースとして、動的に定義されているメソッドについて型注釈を書きたいときがあります。
そのような場合は、@!method
ディレクティブ3を使います。
# @!method bar # @sig () -> void delegate [:bar] => :other
public def bar: () -> void
@rbs
typeエイリアスなど、型注釈以外のrbsコードを書きたくなることがあります。
そのような場合は、module定義の上のコメントに@rbs
に続けて書くと、そのmoduleの中に反映されます。4
# @rbs type key = String | Symbol class App; end
class App type key = String | Symbol end
使用例
実はirbsのソースコード自体がirbsとSteepによって型検査されています。
なのでソースコードと、irbsによって生成されたrbs、型検査のためのRakeタスクを見ていただけると、なんとなく使い方がわかるかと思います。
余談
Sordについて
irbsと似たようなツールとして、YARDからrbsを生成するSordというものがあります。
Sordだと、現状privateなメソッドの型がprivateにならないという問題がありました。
また、型注釈を書くだけならYARDの記法は冗長だと感じます。
# YARD # @param a [Integer] # @param b [Integer] # @return [Integer] def add(a, b) a + b end
# irbs # @sig (Integer, Integer) -> Integer def add(a, b) a + b end
なので型注釈をコメントで書くことに特化したirbsを作ろうと思った次第です。
おわりに
型付きRuby流行ってほしいです。