Slide 1

Slide 1 text

Let's write RBS! RubyKaigi 2023
 13th May


Slide 2

Slide 2 text

● Work for Money Forward, Inc. ○ a Rails app engineer ○ an RBS maintainer ● Live in Okayama ● NOT flat earth believer Masataka Pocke Kuwabara GitHub: @pocke Twitter: @p_ck_ @[email protected]

Slide 3

Slide 3 text

Before this talk, thanks for all RBS contributors!👏👏 4geru, AaronLasseigne, DmitryPogrebnoy, HoneyryderChuck, M-Yamashita01, MITSUBOSHI, MSP-Greg, POPPIN-FUMI, ParadoxV5, TsubasaKawajiri, VTRyo, akito-fujisaki, autopp, buzztaiki, castwide, cky, coorasse, craftscat, dleavitt, fabon-f, fugakkbn, hana-da, hanazuki, hjwylde, hsbt, ioquatix, joker1007, kachick, kaiquekandykoga, kenchan, koic, kotaokubo, koukikitamura, ksss, kymmt90, lauratpa, m11o, mame, meqif, myronmarston, nipe0324, nobu, nogtk, nurse, nvh0412, osatoh, osyo-manga, palkan, paracycle, piotaixr, pocke, raosush, rmitchell-sq, sadgb, sanfrecce-osaka, sevenc-nanashi, shugo, snaka, soutaro, sue445, takahashim, tatematsu-k, thinca, tisonkun, tlvu2697, ujihisa, unasuke, ursm, yassenb, ybiquitous, ydah, yyamanoi1222, yykamei, znz All contributors to ruby/rbs and ruby/gem_rbs_collection from the previous list in the past Kaigi to RBS 3.1 except dependabot.
 This is generated with the following script: https://gist.github.com/pocke/ef809d411bd7f26f02e5850d44db82f2


Slide 4

Slide 4 text

Agenda

Slide 5

Slide 5 text

Agenda This talks has two parts.
 ● Part 1: Introduce RBS features
 ○ Introduce new features of RBS 3.1
 ○ Introduce rbs tools to write signatures (I don't have enough time!)
 ● Part 2: Demonstrate writing RBS
 ○ in an application
 ○ in ruby/rbs repository (I don't have enough time!)


Slide 6

Slide 6 text

● RBS basics
 ○ syntax, usage, etc
 ○ rbs collection
 ● RBS related tools
 ○ Steep, RBS Rails, etc
 I wrote an article to learn them (Japanese). https://pocke.hatenablog.com/entry/2023/ 05/08/184814
 What I will NOT talk about in this presentation

Slide 7

Slide 7 text

The new features of RBS 3.1

Slide 8

Slide 8 text

rbs subtract

Slide 9

Slide 9 text

What is rbs subtract rbs subtract removes duplicate RBS definitions.
 Usage:
 # Display the result of (a.rbs - b.rbs) $ rbs subtract a.rbs b.rbs # Overwrite a.rbs with the result directly $ rbs subtract --write a.rbs b.rbs This feature was developed by Saito-san (@tadd), and I took over it.

Slide 10

Slide 10 text

rbs subtract behavior $ rbs subtract a.rbs b.rbs # output (a.rbs - b.rbs) class C def bar: () -> untyped end # a.rbs class C def foo: () -> untyped def bar: () -> untyped end # b.rbs class C def foo: () -> Integer end You can find more examples from https://github.com/ruby/rbs/blob/master/test/rbs/subtractor_test.rb


Slide 11

Slide 11 text

Why rbs subtract is necessary It is necessary to modify auto-generated RBS files in a maintainable way.


Slide 12

Slide 12 text

● You are developing a large Ruby app, and you want to introduce RBS to the app.
 ● You run an RBS generator.
 ○ It generate RBS files from your codebase.
 ○ Generator is necessary because it's hard to write RBS files for entire application.
 Why necessary: example situation

Slide 13

Slide 13 text

Generated code is not perfect.
 $ cat test.rb class C def foo(int) = int.to_s end $ rbs prototype rb test.rb class C def foo: (untyped int) -> untyped end Why necessary: generated RBS

Slide 14

Slide 14 text

If you write a method definition to a separate file, you will get a duplication error.
 Why necessary: problem # auto-generated.rbs class C def foo: (untyped int) -> untyped end # hand-written.rbs class C def foo: (Integer int) -> String end # ::C#foo has duplicated definitions in hand-written.rbs

Slide 15

Slide 15 text

rbs subtract solves this problem.
 It removes well-described method definitions from auto-generated RBS files.
 
 Why necessary: solution # auto-generated.rbs class C def foo: (untyped int) -> untyped end # hand-written.rbs class C def foo: (Integer int) -> String end # subtracted.rbs class C # No `foo` definition end

Slide 16

Slide 16 text

# Generate RBSs for all Ruby code under sig/prototype directory $ rbs prototype rb --out-dir=sig/prototype --base-dir=. app lib # Write type definitions by hand $ $EDITOR sig/hand-written/foo.rbs # Remove hand-written methods from generated RBSs $ rbs subtract --write sig/prototype sig/rbs_rails sig/hand-written # Type-check with the RBS files $ steep check A simple example workflow

Slide 17

Slide 17 text

This feature is implemented in ruby/rbs#1287.
 The design is described in a HackMD document. https://hackmd.io/seoMijXwRdG2uFITm2lLq w
 For more information

Slide 18

Slide 18 text

rbs parse

Slide 19

Slide 19 text

What is rbs parse ● rbs parse parses a .rbs file and report syntax errors.
 $ rbs parse valid.rbs # Print nothing $ rbs parse invalid.rbs test.rbs:4:0...4:3: Syntax error: cannot start a declaration, token=`end` (kEND) This feature is available since the first release (ruby/rbs#207).


Slide 20

Slide 20 text

What's New Two kinds of options has been available since RBS v3.1 (ruby/rbs#1252).
 ● -e CODE ○ Same as Ruby.
 ○ We can use this command without saving RBS code to a file.
 ● --type, --method-type ○ It specifies parsing context.


Slide 21

Slide 21 text

Unfortunately I do not have enough time. Skip the next slides…

Slide 22

Slide 22 text

Example: -e Previously we need to save RBS code to a file to run rbs parse
 $ $EDITOR test.rbs && rbs parse test.rbs Since RBS 3.1, you do not need to save a file.
 $ rbs parse -e "class C end"

Slide 23

Slide 23 text

Example: --type and --method-type These option is useful with -e.
 # Check whole RBS code $ rbs parse -e "class C def f: (Integer) -> { code: Integer } end" # Check only method type $ rbs parse --method-type -e "(Integer) -> { code: Integer }" # Check only type $ rbs parse --type -e "{ code: Integer }"

Slide 24

Slide 24 text

Other tools (skip)

Slide 25

Slide 25 text

rbs collection ● It manages dependent libraries' RBSs.
 ● In short, Bundler for RBS.
 See my slides at RubyKaigi Takeout 2021 for more details https://rubykaigi.org/2021-tak eout/presentations/p_ck_.html


Slide 26

Slide 26 text

rbs prototype rbs prototype generates RBS from Ruby code.
 I use rbs prototype rb in the demo.


Slide 27

Slide 27 text

Other tools I also uses the following tools in the demonstration.
 ● Steep
 ○ Steep is a type checker working on RBS.
 ○ https://github.com/soutaro/steep
 ● RBS Rails
 ○ RBS Rails is an RBS generator for Rails applications.
 ○ https://github.com/pocke/rbs_rails


Slide 28

Slide 28 text

Editor integrations

Slide 29

Slide 29 text

Editor Integrations Today I use VS Code and the following two extensions for the demonstration.
 ● RBS Syntax
 ● Steep
 But you can also uses other editors that support LSP.
 https://github.com/ruby/rbs/blob/master/d ocs/tools.md
 


Slide 30

Slide 30 text

Demonstrations

Slide 31

Slide 31 text

Demonstrations There are two one demos.
 ● Introduce RBS to an existing app
 ○ On ruby/rubyci
 ● Show development experience using RBS
 ○ On ruby/rbs


Slide 32

Slide 32 text

https://github.com/ruby/rubyci
 1. Introduce rbs collection
 2. Introduce Steep
 3. Introduce rbs subtract
 4. Write .rbs files with subtract
 Introduce RBS to an existing app

Slide 33

Slide 33 text

After Events

Slide 34

Slide 34 text

【Money Forward x Shippio】 BaySide Tech Nite ● Shippio and Money Forward host this event.
 ● Talk about RubyKaigi and Ruby in English
 ● 2023-05-19 Tokyo
 https://moneyforward.connpass.co m/event/281065/
 Unfortunately I cannot attend this event😢


Slide 35

Slide 35 text

● I, mame-san, and sinsoku-san will talk about OSS contribution in this event.
 ● 2023-05-25 Tokyo and Online
 ● Talk in Japanese
 https://timeedev.connpass.com/event/ 279568/
 
 
 OSSへのコントリビュート - Techmee vol.7 (Contribute to OSS)

Slide 36

Slide 36 text

Conclusion

Slide 37

Slide 37 text

● I shared new features of RBS 3.1 ○ rbs subtract is a useful tool when you introduce RBS to a large app.
 ○ rbs prase evolved with new options.
 ● I shared demonstrations of introducing RBS.
 
 Thanks for listening to my talk!
 Conclusion \ WE ARE HIRING / Scan to apply now!