RBS Tutorial
RubyWorld Conference 2023
9th, Nov. 2023

pp self●●Masataka Pocke KuwabaraWork for Money Forward, Inc.
○○●

クラウド会計Plus
A maintainer of RBS

Live in Okayama

Matsue and me

Goal
●

You can start developing applications with RBS○●

without confusion.

You can ﬁnd references to learn RBS.

Agenda●Describe `.rbs` ﬁles
○

●
●
●
●

The diﬀerence from .rb ﬁles

RBS Syntax Overview
How to start RBS
Libraries
References

This talk is based on the premise that it uses RBS and Steep.

What is .rbs ﬁleWhat is .rbs ﬁleIt deﬁnes static types for `.rb` ﬁle.
●●

It is separated from `.rb` ﬁle.
`.rbs` is not a Ruby ﬁle. RBS has diﬀerent syntax from Ruby.

Separated from .rb ﬁle●Basically, `.rb` ﬁle does not contain type information.
○●●

All type deﬁnitions have to be written in RBS ﬁles.

It is similar to (.c and .h) or (.js and .d.ts).
RBS environment is created only from .rbs ﬁle.
○If .rb ﬁle contains a class deﬁnition, RBS does not recognize the class without deﬁnitionin .rbs ﬁle.

In the future (nothing determined)●RBS may support writing RBS in .rb ﬁles○●For example, as a comment (It is just an example!)class C# @rbs: (Integer) -> Stringdef f(int) = int.to_s
end

RBS may relax unknown classes/modules/methods○For example, RBS can generate RBS deﬁnition from .rb ﬁles on runtime

RBS Syntax Overview

RBS Syntax
I'll describe RBS syntax overview.
It is similar to Ruby syntax, but it is diﬀerent.

Classes / Modules# Ruby# RBSmodule M
endmodule M
endclass CX = 42
include M
endclass C
X: Integer
include M
end

C2 = Cclass C2 = C

Method Deﬁnitions# Ruby# RBSclass Cdef f1 = 42
private def f2(int) = int.to_sclass Cdef f1: () -> Integer
private def f2: (Integer int) ->Stringprivatedef f3(&block) = (block.call; 42)
def f4(x:) = x + 42
attr_reader :x
end

privatedef f3: () { () -> void } ->Integerdef f4: (x: Integer) -> Integer
attr_reader x: Integer
endInterfaces# Ruby# RBSclass IO
def read(...)= ...
endinterface _Reader
def read: (?int? length,?string outbuf) -> String?
endclass StringIO
def read(...)= ...
end
def read_from_io(io) = io.read

def read_from_io: (_Reader io) ->String?

Other syntaxes●●●

Type Alias
Type Parametervariables○●●(instance | class | class instance | global) variables`use` directive…and more!

See the following documentation for more information.
https://github.com/ruby/rbs/blob/master/docs/syntax.md

How to start RBS

How to start RBS
I'll describe a minimal example to start developing an app
with RBS / Steep and VS CodeEditor supports●●

Many editors support RBS / SteepTechnically, Steep works on editors supporting LSP

See the full list of editors supporting RBS
https://github.com/ruby/rbs/blob/master/docs/tools.md

VS Code for RBS
I recommend using VS Code because●●

VS Code is well-integrated to LSP
It has oﬃcially developed plugins to integrate RBS○○

https://marketplace.visualstudio.com/items?itemName=soutaro.rbs-syntax
https://marketplace.visualstudio.com/items?itemName=soutaro.steep-vscode

Other editors also support RBS, you can use your favorite editor💕

Prepare gems
Add Steep gem to your Gemﬁlegem "steep", require: false

And run `bundle install`
Note that `gem "rbs"` is not required because Steep depends on RBS gem.

Minimum conﬁguration of Steep# Steepfile
target :lib do
signature "sig"check "lib"check "app"end# Specify where .rbs files are in# Specify where .rb files are in# For Rails app

For more information, see `Steepfile` generated by`steep init`.

Directory structure●You should put RBS ﬁles under `sig/` directory○●

In gem package development, RBS ﬁles under the directory are exposed.

No restriction of directory structure under `sig/`○○○

But I recommend using the same directory structure as the `.rb` ﬁles.
In a Rails app: app/models/user.rb : sig/models/user.rbs
In a gem: lib/foo/bar.rb : sig/foo/bar.rbs

Tips: bin/steep●●●

Steep VS Code plugin supports `bin/steep` executable ﬁle.
If `bin/steep` is available, the plugin uses it instead of `bundle execsteep`
If you need to conﬁgure `steep` command, you can use this ﬁle.

For larger applications●

You can use RBS Rails gem for a Rails application○●●

https://github.com/pocke/rbs_rails

You can use RBS generator, such as `rbs prototype`, to generate RBSof existing Ruby code.
For more information, check out my talk at RubyKaigi 2023○○

https://rubykaigi.org/2023/presentations/p_ck_.html#day3
This talk has demonstration, describing tools such as `rbs subtract`, for large app.

Libraries

Kinds of Libraries●Core Library○○●

Standard Library○○○●

It is installed by default and loaded by default (no require necessary)
Example: Array, String, etc…
It is installed by default, but you need require to load it.
It includes default gems.
Example: pathname, ripper, etc…

Gem
○
○

Other gems, including bundled gems.
Example: activerecord, nokogiri, etc…

See https://stdgems.org/ for the deﬁnition of (default / bundled) gems.

Core Library (Array, String, etc…)
RBS provides core libraries types out of the box●●In Ruby, we do not need require to use a core libraryThen, in RBS, we do not need to do anything to use a core libraryStandard Library (pathname, ripper, etc…)
RBS gem contains their signatures●●

You do not install anything except rbs gem
But you need to specify the gem explicitly to load it○

You can use `rbs collection` for this purposeGem
RBS can load third party gems RBS ﬁles from●●`sig/` directory in gem package
GitHub repository, ruby/gem_rbs_collection

Library management: rbs collection`rbs collection` manages RBSs of gems●

`rbs collection install` installs RBS ﬁles depended by yourapplication○It resolves the dependency from `Gemfile.lock`.

Check my previous talk in RubyKaigi 2021 Takeout for more details
https://rubykaigi.org/2021-takeout/presentations/p_ck_.html

References

Syntax●●

Oﬃcial document:
https://github.com/ruby/rbs/blob/master/docs/syntax.md
My Blog articles:○○●

https://pocke.hatenablog.com/entry/2021/01/02/175940 (2y ago)
https://moneyforward-dev.jp/entry/2023/10/13/rbs-new-syntaxes (only new syntaxes)For developers:○

https://github.com/ruby/rbs/blob/master/ext/rbs_extension/parser.c

Ofﬁcial documents
See docs/ directory https://github.com/ruby/rbs/tree/master/docs●

I recommend the following document for beginners○●

https://github.com/ruby/rbs/blob/master/docs/rbs_by_example.md

You can ﬁnd editor integrations from this document○

https://github.com/ruby/rbs/blob/master/docs/tools.md

Existing RBSs
You can ﬁnd `.rbs` ﬁles from the following places●●●

Core Libraries: https://github.com/ruby/rbs/tree/master/coreStandard Libraries: https://github.com/ruby/rbs/tree/master/stdlib
Gems: https://github.com/ruby/gem_rbs_collection

My Talks●

The newsletter of RBS (RubyKaigi Takeout 2021)
https://speakerdeck.com/pocke/the-newsletter-of-rbs-updates○●

It mainly describes `rbs collection`.

Let's write RBS! (RubyKaigi 2023)
https://speakerdeck.com/pocke/lets-write-rbs○

It mainly describes `rbs subtract`.

Thanks for yourlistening!