DEV Community

loading...

hello gem steep

Yuta Goto
hello
・1 min read

Ruby3.0から静的型チェックする機能が追加されるということで、軽く触ったので備忘録です。

SteepというGemを使いました。

GitHub logo soutaro / steep

Gradual Typing for Ruby

Steep - Gradual Typing for Ruby

Installation

Install via RubyGems.

$ gem install steep

Requirements

Steep requires Ruby 2.6.

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
  def country:

練習リポジトリ


結果

やっていること

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.rbhello2 に代入するときの Helloinitialize するときの引数の型が違っています。ただこのまま実行してもとくにエラーもなく実行することができます。
このあたりもチェックさせることができます。

$ 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プロジェクトに取り込めそうでちょっと型安全になるかもしれません。

Discussion (0)