Merry Christmas! Today Ruby 3.0 was released today with type checking. Here’s how to try it out yourself. First, read about Ruby 3.0 type checking here in The State of Ruby 3 Typing.

Install Ruby 3.0 with rbenv

To follow along, you’ll need Ruby 3.0. I use rbenv. To see the new version 3.0, I updated ruby-version using home brew.

brew upgrade ruby-build

Next, I was able to install the new version using rbenv.

rbenv install 3.0.0

After that, I created a new directory to experiment in.

mkdir PizzaFactory
cd PizzaFactory

I created a .ruby-version file to make sure rbenv was running Ruby 3.0.

echo "3.0.0" > .ruby-version

Double-check you are running Ruby 3.0

ruby -v

You should see the following print out:

ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]

Define a Pizza class

I created a pizza.rb ruby file.

class Pizza

	attr_accessor :toppings
	
	def initialize(toppings)
		@toppings = toppings
	end
	
	def to_s
		toppings.join(", ")
	end
	
end

Annotate the Pizza class with types using an RBS file

Next, I created a sig/pizza.rbs file to describe the types I’ll be using.

class Pizza

	attr_accessor toppings: Array[String]
	
	def initialize: (Array[String]) -> void
	
	def to_s: () -> String
	
end

Check the types with Steep

Install steep to do type checking. I found the steep readme on github helpful:

gem install steep

I ran steep init and it created a Steepfile file, which I modified as shown.

target :pizza do
	signature "sig"

	check "*.rb"
end

I was curious if steep could help me find errors. I created an app.rb file that deliberately included a type error.

require_relative "./pizza"

# Correct type should be: Array[String]
# pizza = Pizza.new(["Pepperoni", "Green Peppers"])

# Incorrect type is passed instead: String 
pizza = Pizza.new("Coffee")

puts pizza.to_s

Check for type errors:

steep check

Success! Well, success in that it found the error I deliberately put in

app.rb:4:18: ArgumentTypeMismatch: receiver=singleton(::Pizza), 
expected=::Array[::String], 
actual=::String ("Coffee")

Closing thoughts

I’ve tried Sorbet briefly too, and I’m not sure yet whether I prefer inline type annotations or external rbs files. Also, hiding the type annotations in a ‘sig’ folder seems a bit odd. I’m used to .h files being in the same directory as their counterpart, and rbs files seem similar to a header file to me. I do love the rbs syntax though.

Kudos to all the developers working on improving Ruby and making the ecosystem richer with type checking. Thank you!

More on the Web About Ruby Types