Ruby3.0から静的型チェックする機能が追加されるということで、軽く触ったので備忘録です。
SteepというGemを使いました。
Steep - Gradual Typing for Ruby
Installation
Install via RubyGems.
$ gem install steep
Requirements
Steep requires Ruby 2.6 or later.
Usage
Steep does not infer types from Ruby programs, but requires declaring types and writing annotations You have to go on the following three steps.
0. steep init
Run steep init
to generate a configuration file.
$ steep init # Generates Steepfile
Edit the Steepfile
:
target :app do
check "lib"
signature "sig"
library "set", "pathname"
end
1. Declare Types
Declare types in .rbs
files in sig
directory.
class Person
@name: String
@contacts: Array[Email | Phone]
def initialize: (name: String) -> untyped
def name: -> String
def contacts: -> Array[Email | Phone]
def guess_country: -> (String | nil)
end
class Email
@address: String
def initialize: (address: String) -> untyped
def address: -> String
end
class Phone
@country: String
@number: String
def initialize: (country: String, number: String) -> untyped
…練習リポジトリ
結果
やっていること
lib/
ディレクトリにいつもどおりにクラスを定義します。
# lib/hello.rb
class Hello
def initialize(name)
@name = name
end
def say
"hello, #{@name}"
end
end
sig/
ディレクトリに型の定義を書いていきます。拡張子は .rbi
になります。
# sig/hello.rbi
class Hello < Object
@name: String
def initialize: (String) -> any
def say: -> String
end
メインで使ってみます。
# app.rb
require "./lib/hello"
hello1 = Hello.new('John')
puts hello1.say
hello2 = Hello.new(123)
puts hello2.say
この app.rb
は hello2
に代入するときの Hello
を initialize
するときの引数の型が違っています。ただこのまま実行してもとくにエラーもなく実行することができます。
このあたりもチェックさせることができます。
$ bundle exec steep check --fallback-any-is-error app.rb
app.rb:6:19: ArgumentTypeMismatch: receiver=::Hello.class constructor, expected=::String, actual=::Integer (123)
6行目のところで引数の型が違うことを指摘してくれたので、成功です。
所管
シンプルなクラス定義などではかなり簡単に使うことができて、とてもよさそうです。
RailsのモデルメソッドやServiceクラスなど部分的にもRailsプロジェクトに取り込めそうでちょっと型安全になるかもしれません。
Top comments (0)