Type checking in Ruby - Mykhailo Bortnyk | Ruby Meditation 31

Ruby Meditation
Ruby MeditationRuby Meditation
Type checking in Ruby
A brief review of modern
type-checking tools
Situation with type checking
Situation with type checking
● Type checkers
○ Sorbet
○ Steep
○ RBS tests
● Type signatures
○ Sorbet RBI
○ RBS
● Type signatures generators
○ Sorbet
○ RBS prototype
○ Typeprof
RBS toolset
RBS commands
● ast - prints JSON representation of AST of loaded environment
● list - lists classes, modules and signatures in type system
● ancestors - shows ancestors of given class or module
● methods - shows methods defined in given class or module
● method - shows type signature and information about given method
● validate - validates RBS files
● constant - resolves constant based on RBS
● paths - list of included paths of type signatures
● prototype - generates prototypes of RBS signatures
● vendor - vendors signatures inside project directory
● parse - parses given signature files and outputs errors
● test - to observe tests to ensure signatures are correct
class Calculator
attr_reader :arg1, :arg2
def initialize(arg1, arg2)
@arg1 = arg1
@arg2 = arg2
end
def add; arg1 + arg2; end
def mul; arg1 * arg2; end
def div; arg1 / arg2; end
def sub; arg1 / arg2; end
def call(method_name)
case method_name
when :add then add
when :mul then mul
when :div then div
when :sub then sub
end
end
end
First signature.RB try
class Calculator
attr_reader arg1: untyped
attr_reader arg2: untyped
def initialize: (untyped arg1, untyped arg2) ->
untyped
def add: () -> untyped
def mul: () -> untyped
def div: () -> untyped
def sub: () -> untyped
def call: (untyped method_name) -> untyped
end
class Calculator
attr_reader :arg1, :arg2
def initialize(arg1, arg2)
@arg1 = arg1
@arg2 = arg2
end
def add; arg1 + arg2; end
def mul; arg1 * arg2; end
def div; arg1 / arg2; end
def sub; arg1 / arg2; end
def call(method_name)
case method_name
when :add then add
when :mul then mul
when :div then div
when :sub then sub
end
end
end
First signature.Runtime try
class Calculator
public
def add: () -> untyped
def arg1: () -> untyped
def arg2: () -> untyped
def call: (untyped method_name) -> untyped
def div: () -> untyped
def mul: () -> untyped
def sub: () -> untyped
private
def initialize: (untyped arg1, untyped arg2) ->
untyped
end
# typed: true
class Test
extend T::Sig
sig {params(x: Integer).void}
def foo(x)
puts(x + 1)
end
end
Migration from Sorbet signatures
class Test
def foo: (Integer x) -> void
end
VariadicUntypedFunction = T.type_alias { Proc }
AssociationCallback = T.type_alias do
T.nilable(
T.any(
Symbol,
String,
T.proc.void,
Proc,
T::Array[T.any(Symbol, Proc, T.proc.void)]
)
)
end
Migration from Sorbet signatures,complex example
# converted example
VariadicUntypedFunction: untyped
AssociationCallback: untyped
# real conversion
type variadic_untyped_function = Proc
type association_callback = (Symbol | String | void |
Proc | Array[(Symbol | Proc | void)])?
class Calculator
attr_reader :arg1, :arg2
def initialize(arg1, arg2)
@arg1 = arg1
@arg2 = arg2
end
def add; arg1 + arg2; end
def mul; arg1 * arg2; end
def div; arg1 / arg2; end
def sub; arg1 / arg2; end
def call(method_name)
case method_name
when :add then add
when :mul then mul
when :div then div
when :sub then sub
end
end
end
First signature.Merged example
class Calculator
public
type result = Integer | Float
attr_reader arg1: result
attr_reader arg2: result
def add: () -> result
def mul: () -> result
def div: () -> result
def sub: () -> result
def call: (Symbol method_name) -> result
private
def initialize: (result arg1, result arg2) -> result
end
Typeprof
Typeprof is a custom-built interpreter which creates type signatures based
on abstract execution. Non-reachable methods produce untyped stubs.
Specifics:
● Needs entry point
● Meta-programming is only partially supported
● Doesn’t handle metaclasses
● Supports only Array and Hash container types
Deeper look on container types
class Stub
def initialize
@x = ["Container"]
@y = { order: 1, value: "Some value" }
end
def foo
@x
end
def bar
@y
end
end
p Stub.new.foo
p Stub.new.bar
# Revealed types
# test_4.rb:16 #=> [String]
# test_4.rb:17 #=> {order: Integer, value: String}
# Classes
class Stub
@x: [String]
@y: {order: Integer, value: String}
def initialize: -> {order: Integer, value: String}
def foo: -> [String]
def bar: -> {order: Integer, value: String}
end
# The maximum depth of nested arrays and hashes is
limited to 5.
Try it online!
https://mame.github.io/typeprof-playground
How to build your signatures
● Generate stubs with rbs prototype rb file_name.rb
● Execute typeprof with some Kernel#p calls to reveal types
● Run prototyping by rbs prototype runtime
● Add missing, correct signatures
Type checking
Steps to work with steep
● steep init to generate Steepfile
● steep check to perform typechecks
● steep stats to show type stats
target :lib do
signature "sig"
check "lib" # Directory name
check "Gemfile" # File name
# ignore "lib/templates/*.rb"
# library "pathname", "set" # Standard
libraries
# library "strong_json" # Gems
end
target :spec do
signature "sig", "sig-private"
check "spec"
# library "pathname", "set" # Standaard
libraries
# library "rspec"
end
Steps to work with steep
● steep init to generate Steepfile
● steep check to perform typechecks
● steep stats to show type stats
target :lib do
signature "sig"
check "lib" # Directory name
check "Gemfile" # File name
# ignore "lib/templates/*.rb"
# library "pathname", "set" # Standard
libraries
# library "strong_json" # Gems
end
target :spec do
signature "sig", "sig-private"
check "spec"
# library "pathname", "set" # Standaard
libraries
# library "rspec"
end
Can I use it on production?
● Well, you can. It promises a lot of fun
● Lack of proper metaprogramming support
● A lot of signatures generation tools, no perfect
● Demands explicitness
● Dislikes splats
● Use it on your own risk
thanks!
Any questions?
1 of 19

Recommended

Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30 by
Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30Ruby Meditation
207 views22 slides
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky... by
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Ruby Meditation
462 views141 slides
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29 by
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Ruby Meditation
210 views49 slides
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ... by
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Ruby Meditation
1.6K views59 slides
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 by
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 Ruby Meditation
366 views23 slides
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28 by
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28Ruby Meditation
459 views20 slides

More Related Content

More from Ruby Meditation

Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio... by
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Ruby Meditation
320 views80 slides
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or... by
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...Ruby Meditation
285 views49 slides
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27 by
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27Ruby Meditation
1.1K views96 slides
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26 by
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26Ruby Meditation
577 views56 slides
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26 by
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Ruby Meditation
299 views51 slides
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (... by
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Ruby Meditation
455 views78 slides

More from Ruby Meditation(20)

Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio... by Ruby Meditation
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Ruby Meditation320 views
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or... by Ruby Meditation
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
Ruby Meditation285 views
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27 by Ruby Meditation
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
Ruby Meditation1.1K views
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26 by Ruby Meditation
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26
Ruby Meditation577 views
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26 by Ruby Meditation
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Ruby Meditation299 views
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (... by Ruby Meditation
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Ruby Meditation455 views
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26 by Ruby Meditation
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Ruby Meditation204 views
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25 by Ruby Meditation
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Ruby Meditation577 views
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita... by Ruby Meditation
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Ruby Meditation511 views
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me... by Ruby Meditation
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Ruby Meditation299 views
Rails App performance at the limit - Bogdan Gusiev by Ruby Meditation
Rails App performance at the limit - Bogdan GusievRails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan Gusiev
Ruby Meditation418 views
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23 by Ruby Meditation
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
Ruby Meditation179 views
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton... by Ruby Meditation
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Ruby Meditation2.7K views
Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio... by Ruby Meditation
 Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio... Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio...
Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio...
Ruby Meditation824 views
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita... by Ruby Meditation
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...
Ruby Meditation340 views
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23 by Ruby Meditation
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23
Ruby Meditation202 views
Residence permit EU - Gennadii Miroshnychenko by Ruby Meditation
Residence permit EU - Gennadii MiroshnychenkoResidence permit EU - Gennadii Miroshnychenko
Residence permit EU - Gennadii Miroshnychenko
Ruby Meditation157 views
Practical SOLID with Rails - Andrii Savchenko by Ruby Meditation
Practical SOLID with Rails - Andrii SavchenkoPractical SOLID with Rails - Andrii Savchenko
Practical SOLID with Rails - Andrii Savchenko
Ruby Meditation140 views
Inside Out Ruby: Using MRI as a C library - Artur Pyrogovskyi by Ruby Meditation
Inside Out Ruby: Using MRI as a C library - Artur PyrogovskyiInside Out Ruby: Using MRI as a C library - Artur Pyrogovskyi
Inside Out Ruby: Using MRI as a C library - Artur Pyrogovskyi
Ruby Meditation151 views

Recently uploaded

Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O... by
Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...
Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...ShapeBlue
88 views13 slides
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlue by
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlueElevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlue
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlueShapeBlue
179 views7 slides
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlue by
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlueWhat’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlue
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlueShapeBlue
222 views23 slides
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ... by
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...ShapeBlue
85 views10 slides
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT by
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBITUpdates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBITShapeBlue
166 views8 slides
Cencora Executive Symposium by
Cencora Executive SymposiumCencora Executive Symposium
Cencora Executive Symposiummarketingcommunicati21
139 views14 slides

Recently uploaded(20)

Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O... by ShapeBlue
Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...
Declarative Kubernetes Cluster Deployment with Cloudstack and Cluster API - O...
ShapeBlue88 views
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlue by ShapeBlue
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlueElevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlue
Elevating Privacy and Security in CloudStack - Boris Stoyanov - ShapeBlue
ShapeBlue179 views
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlue by ShapeBlue
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlueWhat’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlue
What’s New in CloudStack 4.19 - Abhishek Kumar - ShapeBlue
ShapeBlue222 views
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ... by ShapeBlue
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...
ShapeBlue85 views
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT by ShapeBlue
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBITUpdates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT
ShapeBlue166 views
Setting Up Your First CloudStack Environment with Beginners Challenges - MD R... by ShapeBlue
Setting Up Your First CloudStack Environment with Beginners Challenges - MD R...Setting Up Your First CloudStack Environment with Beginners Challenges - MD R...
Setting Up Your First CloudStack Environment with Beginners Challenges - MD R...
ShapeBlue132 views
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or... by ShapeBlue
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
ShapeBlue158 views
Hypervisor Agnostic DRS in CloudStack - Brief overview & demo - Vishesh Jinda... by ShapeBlue
Hypervisor Agnostic DRS in CloudStack - Brief overview & demo - Vishesh Jinda...Hypervisor Agnostic DRS in CloudStack - Brief overview & demo - Vishesh Jinda...
Hypervisor Agnostic DRS in CloudStack - Brief overview & demo - Vishesh Jinda...
ShapeBlue120 views
Future of AR - Facebook Presentation by Rob McCarty
Future of AR - Facebook PresentationFuture of AR - Facebook Presentation
Future of AR - Facebook Presentation
Rob McCarty62 views
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online by ShapeBlue
KVM Security Groups Under the Hood - Wido den Hollander - Your.OnlineKVM Security Groups Under the Hood - Wido den Hollander - Your.Online
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online
ShapeBlue181 views
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And... by ShapeBlue
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...
ShapeBlue63 views
The Role of Patterns in the Era of Large Language Models by Yunyao Li
The Role of Patterns in the Era of Large Language ModelsThe Role of Patterns in the Era of Large Language Models
The Role of Patterns in the Era of Large Language Models
Yunyao Li80 views
Business Analyst Series 2023 - Week 4 Session 7 by DianaGray10
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7
DianaGray10126 views
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas... by Bernd Ruecker
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
Bernd Ruecker50 views
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue by ShapeBlue
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlueVNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue
ShapeBlue163 views
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f... by TrustArc
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...
TrustArc Webinar - Managing Online Tracking Technology Vendors_ A Checklist f...
TrustArc160 views
Why and How CloudStack at weSystems - Stephan Bienek - weSystems by ShapeBlue
Why and How CloudStack at weSystems - Stephan Bienek - weSystemsWhy and How CloudStack at weSystems - Stephan Bienek - weSystems
Why and How CloudStack at weSystems - Stephan Bienek - weSystems
ShapeBlue197 views
Backup and Disaster Recovery with CloudStack and StorPool - Workshop - Venko ... by ShapeBlue
Backup and Disaster Recovery with CloudStack and StorPool - Workshop - Venko ...Backup and Disaster Recovery with CloudStack and StorPool - Workshop - Venko ...
Backup and Disaster Recovery with CloudStack and StorPool - Workshop - Venko ...
ShapeBlue144 views
Confidence in CloudStack - Aron Wagner, Nathan Gleason - Americ by ShapeBlue
Confidence in CloudStack - Aron Wagner, Nathan Gleason - AmericConfidence in CloudStack - Aron Wagner, Nathan Gleason - Americ
Confidence in CloudStack - Aron Wagner, Nathan Gleason - Americ
ShapeBlue88 views

Type checking in Ruby - Mykhailo Bortnyk | Ruby Meditation 31

  • 1. Type checking in Ruby A brief review of modern type-checking tools
  • 3. Situation with type checking ● Type checkers ○ Sorbet ○ Steep ○ RBS tests ● Type signatures ○ Sorbet RBI ○ RBS ● Type signatures generators ○ Sorbet ○ RBS prototype ○ Typeprof
  • 5. RBS commands ● ast - prints JSON representation of AST of loaded environment ● list - lists classes, modules and signatures in type system ● ancestors - shows ancestors of given class or module ● methods - shows methods defined in given class or module ● method - shows type signature and information about given method ● validate - validates RBS files ● constant - resolves constant based on RBS ● paths - list of included paths of type signatures ● prototype - generates prototypes of RBS signatures ● vendor - vendors signatures inside project directory ● parse - parses given signature files and outputs errors ● test - to observe tests to ensure signatures are correct
  • 6. class Calculator attr_reader :arg1, :arg2 def initialize(arg1, arg2) @arg1 = arg1 @arg2 = arg2 end def add; arg1 + arg2; end def mul; arg1 * arg2; end def div; arg1 / arg2; end def sub; arg1 / arg2; end def call(method_name) case method_name when :add then add when :mul then mul when :div then div when :sub then sub end end end First signature.RB try class Calculator attr_reader arg1: untyped attr_reader arg2: untyped def initialize: (untyped arg1, untyped arg2) -> untyped def add: () -> untyped def mul: () -> untyped def div: () -> untyped def sub: () -> untyped def call: (untyped method_name) -> untyped end
  • 7. class Calculator attr_reader :arg1, :arg2 def initialize(arg1, arg2) @arg1 = arg1 @arg2 = arg2 end def add; arg1 + arg2; end def mul; arg1 * arg2; end def div; arg1 / arg2; end def sub; arg1 / arg2; end def call(method_name) case method_name when :add then add when :mul then mul when :div then div when :sub then sub end end end First signature.Runtime try class Calculator public def add: () -> untyped def arg1: () -> untyped def arg2: () -> untyped def call: (untyped method_name) -> untyped def div: () -> untyped def mul: () -> untyped def sub: () -> untyped private def initialize: (untyped arg1, untyped arg2) -> untyped end
  • 8. # typed: true class Test extend T::Sig sig {params(x: Integer).void} def foo(x) puts(x + 1) end end Migration from Sorbet signatures class Test def foo: (Integer x) -> void end
  • 9. VariadicUntypedFunction = T.type_alias { Proc } AssociationCallback = T.type_alias do T.nilable( T.any( Symbol, String, T.proc.void, Proc, T::Array[T.any(Symbol, Proc, T.proc.void)] ) ) end Migration from Sorbet signatures,complex example # converted example VariadicUntypedFunction: untyped AssociationCallback: untyped # real conversion type variadic_untyped_function = Proc type association_callback = (Symbol | String | void | Proc | Array[(Symbol | Proc | void)])?
  • 10. class Calculator attr_reader :arg1, :arg2 def initialize(arg1, arg2) @arg1 = arg1 @arg2 = arg2 end def add; arg1 + arg2; end def mul; arg1 * arg2; end def div; arg1 / arg2; end def sub; arg1 / arg2; end def call(method_name) case method_name when :add then add when :mul then mul when :div then div when :sub then sub end end end First signature.Merged example class Calculator public type result = Integer | Float attr_reader arg1: result attr_reader arg2: result def add: () -> result def mul: () -> result def div: () -> result def sub: () -> result def call: (Symbol method_name) -> result private def initialize: (result arg1, result arg2) -> result end
  • 11. Typeprof Typeprof is a custom-built interpreter which creates type signatures based on abstract execution. Non-reachable methods produce untyped stubs. Specifics: ● Needs entry point ● Meta-programming is only partially supported ● Doesn’t handle metaclasses ● Supports only Array and Hash container types
  • 12. Deeper look on container types class Stub def initialize @x = ["Container"] @y = { order: 1, value: "Some value" } end def foo @x end def bar @y end end p Stub.new.foo p Stub.new.bar # Revealed types # test_4.rb:16 #=> [String] # test_4.rb:17 #=> {order: Integer, value: String} # Classes class Stub @x: [String] @y: {order: Integer, value: String} def initialize: -> {order: Integer, value: String} def foo: -> [String] def bar: -> {order: Integer, value: String} end # The maximum depth of nested arrays and hashes is limited to 5.
  • 14. How to build your signatures ● Generate stubs with rbs prototype rb file_name.rb ● Execute typeprof with some Kernel#p calls to reveal types ● Run prototyping by rbs prototype runtime ● Add missing, correct signatures
  • 16. Steps to work with steep ● steep init to generate Steepfile ● steep check to perform typechecks ● steep stats to show type stats target :lib do signature "sig" check "lib" # Directory name check "Gemfile" # File name # ignore "lib/templates/*.rb" # library "pathname", "set" # Standard libraries # library "strong_json" # Gems end target :spec do signature "sig", "sig-private" check "spec" # library "pathname", "set" # Standaard libraries # library "rspec" end
  • 17. Steps to work with steep ● steep init to generate Steepfile ● steep check to perform typechecks ● steep stats to show type stats target :lib do signature "sig" check "lib" # Directory name check "Gemfile" # File name # ignore "lib/templates/*.rb" # library "pathname", "set" # Standard libraries # library "strong_json" # Gems end target :spec do signature "sig", "sig-private" check "spec" # library "pathname", "set" # Standaard libraries # library "rspec" end
  • 18. Can I use it on production? ● Well, you can. It promises a lot of fun ● Lack of proper metaprogramming support ● A lot of signatures generation tools, no perfect ● Demands explicitness ● Dislikes splats ● Use it on your own risk