Types in Ruby 3 Multiple type checkers in one blueprint • Ruby Signature The standard type signature format for stdlib and gems • Type Profiler A type analysis for non-annotated Ruby code 5
without execution • To improve development experience (In other words, a few wrong alerts are acceptable) 7 def increment(n) n.timees { } n + "STRING" end increment(42) NoMethodError? TypeError?
you can write annotations if you like • You will gain relatively strong type checking • Moreover, in Ruby 3, • You don't have to write annotations manually • You can even check the code with no annotations! (if my project succeeds ☺) 9
can write annotations if you like • You will gain relatively strong type checking • Moreover, in Ruby 3, • You don't have to write annotations manually • You can even check the code with no annotations! (if my project succeeds ☺) 10
language 2. Type inference for non-annotated code (Type Profiler) 3. Type checking for annotated code (Sorbet, RDL, Steep, etc.) I explain 1 and 2 in this talk... 11
RBS • https://github.com/ruby/ruby-signature • Develops own static type checker "Steep" • [Correction] No session about Steep this year! • Working for Square 13
describe types of Ruby programs • Different syntax: to keep Ruby code unannotated • Ruby3 will ship with signatures for stdlib and a library for RBS 14 class Inc def increment(n) n + 1 end end inc.rbs inc.rb class Inc def increment: (Integer) -> Integer end separated files
/ Sorbet RBI • Generate using Type Profiler • [WIP] A tool to test RBS definitions by dynamic type checking 17 $ rbs scaffold rb # from unannotated Ruby code $ rbs scaffold rbi # from Sorbet annotated code
of code • Written by Hideki Miura • Original version (js) was created by Syoyo Fujita https://code.google.com/archive/p/aobench/ • Analysis time < 1sec. 22
• Can be used as a signature with some fixes • May be also useful for program understanding • There are some wrong / incomplete guesses • Due to lack of knowledge of methods, analysis limitation, etc. • Some of them can be fixed by TP improvement 26
any @audio : any @input : any @cpu : Optcarrot::CPU @apu : Optcarrot::APU @ppu : Optcarrot::PPU initialize : () -> None end Three circuit modules: CPU, APU (Audio), PPU (Graphics) Failed to detect other methods
Due to lack of knowledge about many builtin classes/methods (such as Fiber, etc.) • Still, it looks useful to create a prototype of signatures • TP is never perfect, but I believe it is promising 30
n < 10 n else "error" end end foo(42) Fork! Now here We cannot tell if n<10 or not Object#foo :: (Integer) -> (Integer | String) 32 Returns String Returns Integer
to a wrong guess 36 def foo(n) n+1 end assert_raise { foo("s") } infer def foo: (String) -> any A test excepts an exception def bar(n) n end foo(MockObject.new) A test passes a mock object infer def bar: (MockObject) -> ...
• Singleton methods, Object#eval, binding, etc... • You need manually write RBS in this case 37 def inc(n) n end send("inc".to_sym, 42) infer def inc: (any) -> any The Symbol cannot be determined in type-level
MRI-compatible normal interpreter • Many features are not supported yet • Notable unsupported-yet features: Module, and Exception • The analysis performance must be improved 38 It is developed in one person-year 😖 Help, advice, and contribution are welcome!!!
been inspired by it • Type Analysis for JavaScript (S. H. Jensen, et al.) • RDL infer (Jeff Foster et al.) • An alternative approach to infer types of non-annotated Ruby code • Based on traditional type inference with some heuristics 39
• Introduced Type Profiler • A type analyzer for Ruby 3 applicable to a non-annotated Ruby code • Based on abstract interpretation technique • Little change for Ruby programming experience • Any comments and/or contribution are welcome! • https://github.com/mame/ruby-type-profiler 41