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

The newsletter of RBS updates

September 10, 2021

The newsletter of RBS updates


September 10, 2021

More Decks by pocke

Other Decks in Programming


  1. 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!
  2. 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
  3. 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
  4. 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!
  5. 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
  6. 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+
  7. 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
  8. 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
  9. 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)
  10. 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💎
  11. Motivation Before rbs collection, managing libraries’ RBSs is not smart.

    Let’s look an example to prepare libraries’ RBSs for a Rails app
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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)
  20. 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
  21. 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)
  22. 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.
  23. 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
  24. Bounded Type Parameters RBS v2 will introduce Bounded Type Parameters.

    It allows you to specify an upper bound to Type Parameters.
  25. 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
  26. 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)
  27. 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
  28. 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
  29. 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.
  30. 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!
  31. 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
  32. 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!