Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Let's write RBS!

pocke
May 13, 2023

Let's write RBS!

pocke

May 13, 2023
Tweet

More Decks by pocke

Other Decks in Programming

Transcript

  1. Let's write RBS!
    RubyKaigi 2023

    13th May


    View Slide

  2. ● 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]

    View Slide

  3. 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


    View Slide

  4. Agenda

    View Slide

  5. 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!)


    View Slide

  6. ● 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

    View Slide

  7. The new features
    of RBS 3.1

    View Slide

  8. rbs subtract

    View Slide

  9. 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.

    View Slide

  10. 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


    View Slide

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


    View Slide

  12. ● 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

    View Slide

  13. 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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. # 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

    View Slide

  17. This feature is implemented in
    ruby/rbs#1287.

    The design is described in a HackMD
    document.
    https://hackmd.io/seoMijXwRdG2uFITm2lLq
    w

    For more information

    View Slide

  18. rbs parse

    View Slide

  19. 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).


    View Slide

  20. 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.


    View Slide

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

    View Slide

  22. 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"

    View Slide

  23. 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 }"

    View Slide

  24. Other tools (skip)

    View Slide

  25. 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


    View Slide

  26. rbs prototype
    rbs prototype generates
    RBS from Ruby code.

    I use rbs prototype rb in
    the demo.


    View Slide

  27. 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


    View Slide

  28. Editor integrations

    View Slide

  29. 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


    View Slide

  30. Demonstrations

    View Slide

  31. Demonstrations
    There are two one demos.

    ● Introduce RBS to an existing app

    ○ On ruby/rubyci

    ● Show development experience using RBS

    ○ On ruby/rbs


    View Slide

  32. 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

    View Slide

  33. After Events

    View Slide

  34. 【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😢


    View Slide

  35. ● 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)

    View Slide

  36. Conclusion

    View Slide

  37. ● 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!

    View Slide