LoginSignup
5
1

More than 3 years have passed since last update.

Ruby 3でRBS、TypeProf、Steep(型注釈・型検査)を体験してみる!

Last updated at Posted at 2020-12-27

Ruby3がリリースされました。
Rubyコミッターの皆さん、お疲れ様です。

待ち望んでいた、Rubyの型注釈をやってみる!!

Ruby3をインストール!

rbenvをインストールする。

brew install rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/bash_profile

rbenvからRuby3をインストールする。
インストールできるリストを確認すると、3.0.0があるのを確認。

% rbenv install --list
2.5.8
2.6.6
2.7.2
3.0.0
jruby-9.2.14.0
mruby-2.1.2
rbx-5.0
truffleruby-20.3.0
truffleruby+graalvm-20.3.0

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all / -L' to show all local versions.

Ruby3.0.0をいよいよインストール。

 rbenv install 3.0.0 
 rbenv global 3.0.0

やったー。

% ruby -v               
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]

Rubyの型注釈をやってみる

適当なディレクトリにRubyのコードを書いてみる。
app.rbというファイルに書いてみた。

def plus(x, y)
  x + y
end

puts plus(1,1)

必要なツールをインストールする。
型検査をしてくれるsteepというgemを使う。

gem install steep

Steepfileという設定ファイルを自動生成してもらう。

steep init

Steepfileが生成された。

# target :lib do
#   signature "sig"
#
#   check "lib"                       # Directory name
#   check "Gemfile"                   # File name
#   check "app/models/**/*.rb"        # Glob
#   # ignore "lib/templates/*.rb"
#
#   # library "pathname", "set"       # Standard libraries
#   # library "strong_json"           # Gems
# end

# target :spec do
#   signature "sig", "sig-private"
#
#   check "spec"
#
#   # library "pathname", "set"       # Standard libraries
#   # library "rspec"
# end     

Steepfileを書き換える。

target :lib do
  signature "sig"
  check "app.rb"
end

試しに、型検査をしてみる。

steep check   
app.rb:5:5: NoMethodError: type=::Object, method=plus (plus(1,1))

まだ型注釈を書いてないので、NoMethodErrorとなる。

型注釈を書く

次は、sigディレクトリ以下に型注釈を入れていく。
型注釈は.rbsという拡張子で記述する。

TypeProfというRuby3に付いているツールで自動で生成できる。

typeprof app.rb -o sig/app.rbs

sig/app.rbsが生成された。以下のようになる。

# Classes
class Object
  private
  def plus: (Integer x, Integer y) -> Integer
end

この状態で型検査してみる。

steep check    

すると、何も表示されなかったので型検査が通りました🎉

試しに、IntegerをStringにしてみる。

# Classes
class Object
  private
  def plus: (Integer x, Integer y) -> String
end

すると、このようなエラーとなる。

steep check
app.rb:1:0: MethodBodyTypeMismatch: method=plus, expected=::String, actual=::Integer (def plus(x, y))
  ::Integer <: ::String
   ::Numeric <: ::String
    ::Object <: ::String
     ::BasicObject <: ::String
==> ::BasicObject <: ::String does not hold

まとめ

待ち望んでいた、Rubyの型を体験できてよかった。
TypeProfなどで自動で解析して型注釈を書いてくれるのは独自な機能だし、Matzさんの思想が反映されているのかなぁと感じた。

参考文献

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1