updates • Performance with MJIT • Concurrency with Ractor and Fiber Scheduler • Static typing with RBS and TypeProf ← 👀 https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/
RBS • RBS gem and type de fi nitions of standard libraries • RBS is not a type checker, but a language, fi les, or a library • Several RBS-based tools are available • You choose the best tools for your projects
= Conference.new("RubyConf 2020") # conf.talks << talk1 # conf.talks << talk2 # class Conference # The name of the conference. attr_reader name: String # Talks of the conference. attr_reader talks: Array[Talk] def initialize: (String name) -> void # Yields all speakers of the conference. # Deduped, and no order guaranteed. def each_speaker: { (Speaker) -> void } -> void | () -> Enumerator[Speaker, void] end
conference.talks.push(*talks) conference.each_speaker do |speaker| puts "%s (%s)" % [speaker.name, speaker.email] end Does new method accept a String argument?
conference.talks.push(*talks) conference.each_speaker do |speaker| puts "%s (%s)" % [speaker.name, speaker.email] end Does new method accept a String argument? What is the type of the value of #talks?
conference.talks.push(*talks) conference.each_speaker do |speaker| puts "%s (%s)" % [speaker.name, speaker.email] end Does new method accept a String argument? What is the type of the value of #talks? What is the type of the speaker?
based on RBS • You write types of your Ruby program in RBS, and Steep checks the consistency between the code and RBS • https://github.com/soutaro/steep $ steep check
and URL helpers • It knows how associations and attributes are represented as Ruby objects in Rails app • https://github.com/pocke/rbs_rails $ rake rbs_rails:generate_rbs_for_models \ rbs_rails:generate_rbs_for_path_helpers
supports loading RBS fi les from a gem, but this is for gems without RBS fi les • == De fi nitelyTyped in TypeScript, typeshed in Python https://github.com/ruby/gem_rbs_collection
a class from your project 3. Write RBS for the class (or generate with rbs-prototype) 4. Run Steep to con fi rm your RBS and Ruby code are consistent 5. Goto 2
the tool for everything • Many type errors will be reported and you will give up • You can type check gradually # This won't work well ⚠ $ rbs prototype rb lib/**/*.rb $ steep check
calls and type checks if arguments/return values have expected types • Pros: Easier to use compared to Steep Cons: Slow, unsupported features, incompatibilities $ rbs test --target='Goodcheck::*' \ ruby -Ilib:test test/config_loader_test.rb ... ERROR["test_load_config"] test_load_config#ConfigLoaderTest (0.03s) Minitest::UnexpectedError: TypeError: [Goodcheck::Pattern::Regexp#initialize] ArgumentTypeError: expected `bool` but given `nil` ...
calls and type checks if arguments/return values have expected types • Pros: Easier to use compared to Steep Cons: Slow, unsupported features, incompatibilities $ rbs test --target='Goodcheck::*' \ ruby -Ilib:test test/config_loader_test.rb ... ERROR["test_load_config"] test_load_config#ConfigLoaderTest (0.03s) Minitest::UnexpectedError: TypeError: [Goodcheck::Pattern::Regexp#initialize] ArgumentTypeError: expected `bool` but given `nil` ... Class patterns to type check
calls and type checks if arguments/return values have expected types • Pros: Easier to use compared to Steep Cons: Slow, unsupported features, incompatibilities $ rbs test --target='Goodcheck::*' \ ruby -Ilib:test test/config_loader_test.rb ... ERROR["test_load_config"] test_load_config#ConfigLoaderTest (0.03s) Minitest::UnexpectedError: TypeError: [Goodcheck::Pattern::Regexp#initialize] ArgumentTypeError: expected `bool` but given `nil` ... Class patterns to type check Command line to run Ruby program
Much smarter than rbs-prototype. • Execute the Ruby script at type level, and print the result. Ruby script to start execution $ typeprof exe/goodcheck
RBS (and RBI) fi les using the types included in the comments • https://github.com/AaronC81/sord $ sord defs.rbs • rbs_protobuf runs as a plugin of protoc and translates .proto to RBS type de fi nition • https://github.com/square/rbs_protobuf $ protoc --rbs_out=sig/protos \ protos/a.proto Refer types written by human
Ruby • They plan to support reading (a subset of) RBS • RBI will continue to be the primary type de fi nition format in Sorbet • Supporting RBS will help using gems even without RBI fi les
tools based on RBS • Waiting for your contribution • Writing RBS of gems and push it to gem_rbs_collection • Generating API docs from RBS • I want more Steep users • Let me help you to start type checking your Ruby code using Steep