はじめに
少し前ですが、AWS SDK for Ruby V3に対して型定義情報を提供するRBSが追加されたというアナウンスがありました。
実際にこれを実装したのがksssさんで、そのことをブログ記事にもされています。
RBSについては検証ができていなかったのですが、よく使うAWS SDK for RubyにRBSが含まれることになったので試してみることにしました。
前提条件
今回は、以下のgemのバージョンで試しました。
環境構築
以下の中身を持ったGemfileを作成します。
# frozen_string_literal: true source "https://rubygems.org" gem 'aws-sdk-s3', '~> 1.158' gem 'steep', require: false
bundle install
を実行して、Gemfile.lock
を生成しておきます。
その後、rbs collection init
を実行し、rbs_collection.yaml
を生成します。rbs_collection.yaml
の中身は特に変更せず、rbs collection install
を実行します。これにより、アプリに必要なgemをGemfile.lock
から判断し必要であればRBSファイルをダウンロードされ、rbs_collection.lock.yaml
ファイルが作成されます。今回AWS SDK for RubyにはRBSが含まれることになったので、実際にはダウンロードされないようです。
ちなみに、ここらへんの挙動は以下のブログに詳しく書かれていました。
その後、型チェックをするためにSteepfile
を作成します。Steepfile
の作成には、bundle exec steep init
を実行すると便利です。あらかじめ初期設定がされたSteepfile
が生成されますが、今回は以下のように記述しました。
target :lib do signature "sig" check "lib" library "aws-sdk-s3" end
環境準備は以上で終了です。
型チェック
実際に型チェックを実施してみます。Steepfile
にcheck "lib"
と書いたので、lib
以下にあるファイルがチェック対象となるようです。例えばlib/main.rb
というファイルを作り、以下の内容としてみます。
require 'aws-sdk-s3' client = Aws::S3::Client.new client.create_buckeet(bucket: "aaaaa")
あとは、bundle exec steep check
を実行すると、無事create_buckeet
というメソッドはないよというチェックエラーを検出してくれました。
# Type checking files: .................................................................................................................F.......... lib/main.rb:4:7: [error] Type `::Aws::S3::Client` does not have method `create_buckeet` │ Diagnostic ID: Ruby::NoMethod │ └ client.create_buckeet(bucket: "aaaaa") ~~~~~~~~~~~~~~ Detected 1 problem from 1 file
型のチェックも実施してくれます。例えば、以下のようなプログラムにおいてチェックをかけてみます。
require 'aws-sdk-s3' client = Aws::S3::Client.new client.list_objects_v2(bucket: "aaaaa").contents.each do |obj| obj.etag = 123 end
結果は、以下の通り。etag
にはStringを指定する必要がありますが、Integerが指定されているというチェック結果が出ました。
# Type checking files: .......................................................................................................................F.... lib/main.rb:5:13: [error] Cannot pass a value of type `::Integer` as an argument of type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::ArgumentTypeMismatch │ └ obj.etag = 123 ~~~ Detected 1 problem from 1 file
Visual Studio Codeとの連携
SteepにはVisual Studio CodeのExtensionが用意されています。
これをインストールすることで、Visual Studio Codeのエディタ上でチェック結果が表示されます。
考察
AWS SDK for Ruby V3に導入されたRBSについて実際に検証してみました。今回、aws-sdk
ではなくaws-sdk-s3
に絞ったのは意図的で、aws-sdk
と書いてしまうと、aws-sdk
配下の300以上のgemに対してチェックが行われ、かなり時間がかかります。手元のM2 MacBook Airで数分かかりました。このため、Gemfile
やrbs_collection.yaml
に記述するgemは直接使うものだけを明示したほうが良いかなと感じます。