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

The newsletter of RBS updates

7bc6612fa20296bf652f6b0357db81c1?s=47 pocke
September 10, 2021

The newsletter of RBS updates



September 10, 2021


  1. The newsletter of RBS updates RubyKaigi Takeout 2021🍔💨 Sep. 10th

  2. pp self • Masataka Pocke Kuwabara • Software Engineer at

    Bit Journey, Inc. ◦ Developing Kibela, an information sharing tool. https://kibe.la • A maintainer of RBS • A CRuby committer since Mar. 2021 ← NEW!
  3. First, Thanks for all RBS contributors!👏👏 AaronC81, Adrian-Hirt, Afront, CariWest,

    HoneyryderChuck, MITSUBOSHI, Morriar, PanosCodes, YutaGoto, Yuuki77, a2ikm, ahazem, aikyo02, alts, andrewmcodes, berkos, cky, connorshea, donaldong, duderman, floor114, guillaumebriday, hanachin, hargoniX, hjwylde, hsbt, jeremyevans, jocmp, johansenja, k0kubun, kachick, kddnewton, kmizu, ko1, ksss, kunitoo, kyanny, linhpham, mame, marcandre, masahito1997, meganemura, mihyaeru21, mtsmfm, natsuokawai, nobu, ochaochaocha3, ohbarye, palkan, pocke, pointlessone, raosush, s4na, satoryu, sbeckeriv, soutaro, south37, szTheory, tadd, taki, waka, wat-aro, ybiquitous, ykpythemind, ysakasin note: ascii order, (..Time.parse('2020-08-20').cover?(contributed_at) full list: https://github.com/ruby/rbs/graphs/contributors and https://github.com/ruby/gem_rbs_collection/graphs/contributors
  4. Goal • You get hints to introduce RBS to your

    application • Announce RBS updates for Ruby 3.1 ◦ RBS v2 will be released for Ruby 3.1
  5. Support page This talk is pre-recording, so it may have

    updates between recording and event date. I wrote the additional information into the following GitHub repository. https://github.com/pocke/rubykaigi-2021 And I’m watching this talk so feel free to ask me!
  6. Agenda: RBS Updates • Introduce RBS and related softwares •

    New feature: rbs collection ◦ The main topic! • Language Updates (Thanks soutaro-san!) ◦ Bounded type parameter ◦ Generic type aliases • Other updates ◦ Signature updates ◦ Performance Improvements
  7. Introduce RBS and related softwares

  8. What’s is RBS? • RBS is a language to describe

    Ruby types. • It is a bundled gem since Ruby 3.0. • You can also gem install rbs in Ruby 2.6+
  9. Repositories RBS is developed under two GitHub repositories • https://github.com/ruby/rbs

    ◦ the rbs gem ◦ rbs command, rbs library, and RBS files for Ruby builtin and stdlibs. • https://github.com/ruby/gem_rbs_collection ◦ RBS for 3rd party gems, such as rails, nokogiri, etc ◦ Similar to DefinitelyTyped in TypeScript
  10. Let’s contriubte to ruby/gem_rbs_collection • It’s one of the easiest

    parts to contribute RBS • We recommend writing gem RBS partially ◦ RBS for gem’s all features is not required, focus the main features
  11. Related softwares • TypeProf: https://github.com/ruby/typeprof ◦ A type analysis tool

    for Ruby code based on abstract interpretation • Steep: https://github.com/soutaro/steep ◦ Static Type Checker, using RBS • RBS Rails: https://github.com/pocke/rbs_rails ◦ RBS generator for Ruby on Rails • Sorbet: https://github.com/sorbet/sorbet ◦ Static Type Checker, using RBI (another language describes Ruby Type)
  12. New feature: rbs collection

  13. New feature: rbs colllection • It manages dependent libraries’ RBSs

    ◦ In short, Bundler for RBS • I’m developing this feature • rbs collection command has been released! ◦ As experimental for now, it will be GA on RBS v2 ◦ You can use it with gem install rbs now💎
  14. Motivation Before rbs collection, managing libraries’ RBSs is not smart.

    Let’s look an example to prepare libraries’ RBSs for a Rails app
  15. Motivating Example: Enable RBSs for a Rails app First, download

    gem_rbs_collection as git submodule $ git submodule add https://github.com/ruby/gem_rbs_collection.g it gem_rbs_collection
  16. Motivating Example: Enable RBSs for a Rails app Then, rbs

    command is available with the following super many options! $ rbs -rlogger -rpathname -rmutex_m -rdate -rmonitor -rsingleton -rtsort -rtime --repo=gem_rbs_collection -rrack -ractivesupport -ractionpack -ractivejob -ractivemodel -ractionview -ractiverecord -rrailties validate
  17. Motivating Example: Enable RBSs for a Rails app TypeProf needs

    the same options $ typeprof -rlogger -rpathname -rmutex_m -rdate -rmonitor -rsingleton -rtsort -rtime --repo=gem_rbs_collection -rrack -ractivesupport -ractionpack -ractivejob -ractivemodel -ractionview -ractiverecord -rrailties target.rb
  18. Example: Enable RBSs for a Rails app (step 4) And,

    Steep needs another configuration file, Steepfile. target :app do signature 'sig' check 'app' repo_path "gem_rbs_collection" library 'pathname', 'logger', 'mutex_m', 'date', 'monitor', 'singleton', 'tsort', 'time', 'rack', 'activesupport', 'actionpack', 'activejob', 'activemodel', 'actionview', 'activerecord', 'railties' end
  19. Conclusion of the motivations • We need resolve dependencies by

    hand ◦ The above examples, the human resolves “my app depends on Active Support, then Active Support depends on logger and …” • To download, We need git submodule or copying RBSs ◦ It’s too primitive. How controlling versions of 3rd party RBSs? • To load, We need different ways between RBS, Steep, and TypeProf
  20. rbs collection solves the problems!

  21. What’s rbs collection? • rbs collection is a command to

    manage libraries’ RBSs • It does the following things ◦ Resolve dependencies automatically ◦ Download necessary RBSs ◦ Load RBSs from one configuration file
  22. Usage example: rbs collection for a Rails app First, you

    need to generate the configuration file, rbs_collection.yaml # to install the latest version of RBS $ gem install rbs $ rbs collection init created: rbs_collection.yaml
  23. Usage example: rbs collection for a Rails app Then, edit

    the generated config file, add the following line + gems: [name: pathname, name: logger, name: mutex_m, name: date, name: monitor, name: singleton, name: tsort, name: time, name: set] (I’ll describe meaning of this diff)
  24. Usage example: rbs collection for a Rails app Then install

    RBSs. Note that rbs collection needs Gemfile.lock to resolve the dependencies $ vim Gemfile && bundle install $ rbs collection install
  25. Usage example: rbs collection for a Rails app Finally you

    can use RBS related tools without CLI options! $ rbs validate $ typeprof target.rb $ steep init && steep check Everything is going well! (NOTE: Steep and TypeProf haven’t been implemented yet maybe)
  26. Mechanism of rbs collection

  27. Mechanism of rbs collection • It resolves dependencies with Gemfile.lock,

    and writes them to the lockfile, rbs_collection.lock.yaml • It copies libraries’ RBSs with the lockfile from the sources, ruby/gem_rbs_collection GitHub repo in most cases. • It loads RBSs with the lockfile for rbs, typeprof, steep commands.
  28. Known Issue • rbs collection doesn’t resolve dependencies of standard

    libraries ◦ For example, logger, optparse, etc… ◦ Because standard libraries don’t need to be added to gemspec/Gemfile in order to require. • I’ll fix this problem soon by introducing a configuration file, such as manifest.yaml to each gem
  29. New feature: Bounded Type Parameters

  30. Bounded Type Parameters RBS v2 will introduce Bounded Type Parameters.

    It allows you to specify an upper bound to Type Parameters.
  31. Motivating Example: PrettyPrint class • The first parameter of PrettyPrint.new

    is the destination of printing. ◦ e.g. PrettyPrint.new(str) ◦ The output is given with << method
  32. Motivating Example: PrettyPrint classs PrettyPrint.new("") # OK (String#<<) PrettyPrint.new(STDOUT) #

    OK (IO#<<) PrettyPrint.new([]) # OK (Array#<<) PrettyPrint.new(true) # Error (No TrueClass#<<) PrettyPrint.new(3) # Error (Integer#<< doesn't accept String)
  33. Without bounded type parameters # RBS class PrettyPrint attr_reader output:

    _PPOut def initialize: (?_PPOut output) -> void end interface _PPOut def <<: (String) -> void end # Ruby PrettyPrint.new("") .output.size # _PPOut doesn't have #size PrettyPrint.new([]) .output.join("") # _PPOut doesn't have #join
  34. Bounded type parameters solve this problem # RBS class PrettyPrint[X

    < _PPOut] attr_reader output: X def initialize: (?X output) -> void end interface _PPOut def <<: (String) -> void end # Ruby PrettyPrint.new("") .output.size # X == String, String#size exists PrettyPrint.new([]) .output.join("") # X == Array, Array#join exists
  35. New feature: Generic Type Aliases

  36. Generic Type Aliases RBS v2 will introduce generic type aliases.

  37. Motivating Example: defining tree types type int_tree = { value:

    Integer, left: int_tree?, right: int_tree? } type string_tree = { value: String, left: string_tree?, right: string_tree? } We need to define the most same types for each type.
  38. Generic Type Aliases solve this problem type tree[T] = {

    value: T, left: tree[T]?, right: tree[T]? } type int_tree = tree[Integer] type string_tree = tree[String] type cat_tree = tree[Cat] We can define generic tree[T] type to make them DRY!
  39. Other updates

  40. Other updates • Signature updates ◦ 80 RBS files added/updated

    since RBS v1 for Ruby 3.0 • Performance Improvements ◦ rbs validate command has been 3x faster than RBS v1 ◦ Parsing RBS will be 5x faster by an RBS parser written in C by soutaro-san • Many bug fixes See the CHANGELOG for full changes! https://github.com/ruby/rbs/blob/master/CHANGELOG.md
  41. Conclusion

  42. Conclusion • RBS v2 will introduces many new features, such

    as rbs collection and language updates • It also includes signature updates, performance improvements • We’re developing RBS for Ruby v3.1! Thanks for listening!