Skip to content

Release Note 3.4

Soutaro Matsumoto edited this page Jan 9, 2024 · 7 revisions

Some of the highlights in RBS 3.4 are:

You can install it with $ gem install rbs or using Bundler.

gem 'rbs', '~> 3.4.0'

Read the CHANGELOG for the details.

RBS 3.4 has many stdlib signature updates. Updating to 3.4 may cause having different type checking results.

Improvement on rbs validate (#1648)

@ksss implemented a major improvement on rbs validate. Instead of stopping the validation after the first error is detected, it validates all of the type definitions printing detected problems. It also generates a prettier outputs showing the highlighted line of RBS source code.

$ rbs -I sig validate
E, [2023-12-19T17:41:44.136289 #70306] ERROR -- rbs: sig/rbs.rbs:2:25...2:31: Could not find ::Logger (RBS::NoTypeFoundError)

    def self.logger: () -> Logger
                           ^^^^^^

E, [2023-12-19T17:41:44.136354 #70306] ERROR -- rbs: sig/rbs.rbs:14:16...14:22: Could not find ::Logger (RBS::NoTypeFoundError)

    self.@logger: Logger?
                  ^^^^^^

...

It provides a few options to control the behavior, and you can specify --log-level option if you want more output.

Ruby 3.3 updates (#1689, #1684, #1676, #1674)

RBS 3.4 ships with the update type definitions for Ruby 3.3. Although we still have uncovered methods and modules, it ships with better coverage of Ruby 3.3 updates.

(We released RBS 3.4.1 which ships with updated embedded RDoc based on ruby-3.3.0.)

RBS::UnitTest (#1687, #1660)

RBS ships with rbs/unit_test module that helps writing tests the type definition of your gems. The #assert_send_type is the core assertion that calls a method and validates if given arguments and the return value is compatible with the type definition in RBS.

require "minitest"
require "rbs"
require "rbs/unit_test"

class YourGemClassTest < Minitest::Test
  include RBS::UnitTest::TypeAssertions

  testing "YourGemClass"

  def test_foo
    assert_send_type(
      "(Integer) -> String",
      YourGemClass.new, :foo, 123
    )
  end
end

Do you want to support common to_? methods? You can test them using with_*** helpers, like with_int.

class YourGemClassTest < Minitest::Test
  def test_foo
    with_int(123) do |i|    # `i` will be an Integer or an object with `#to_int` method
      assert_send_type(
        "(int) -> String",
        YourGemClass.new, :foo, i
      )
    end
  end
end

The helpers, originally implemented by @sampersand, yields special objects which implements only #to_int or other conversion methods, and you can make sure your method accepts more types than primitive Integer.