Speakerline
Speakers
Proposals
Events
Tags
Edit a proposal
Adam Cuppy
Ahmed Omran
Alan Ridlehoover
Amit Zur
Andrew Mason
Andrew Nesbitt
Andy Andrea
Andy Croll
Asia Hoe
Avdi Grimm
Ben Greenberg
Bhavani Ravi
Brandon Carlson
Brittany Martin
Caleb Thompson
Caren Chang
Chiu-Ki Chan
Christine Seeman
Cody Norman
Devon Estes
Eileen Uchitelle
Emily Giurleo
Emily Samp
Enrico Grillo
Espartaco Palma
Fito von Zastrow
Frances Coronel
Hilary Stohs-Krause
Jalem Raj Rohit
Jemma Issroff
Jenny Shih
Joel Chippindale
Justin Searls
Katrina Owen
Kevin Murphy
Kudakwashe Paradzayi
Kylie Stradley
Maeve Revels
Maryann Bell
Matt Bee
Mayra Lucia Navarro
Molly Struve
Nadia Odunayo
Nickolas Means
Noah Gibbs
Olivier Lacan
Ramón Huidobro
Richard Schneeman
Rizky Ariestiyansyah
Saron Yitbarek
Sean Moran-Richards
Shem Magnezi
Srushith Repakula
Stefanni Brasil
Sweta Sanghavi
Syed Faraaz Ahmad
Tekin Suleyman
Thomas Carr
Tom Stuart
Ufuk Kayserilioglu
Valentino Stoll
Victoria Gonda
Vladimir Dementyev
Title
Tags (comma-separated, max 3)
Body
### Abstract As part of our adoption process of Sorbet at Shopify, we needed an automated way to teach Sorbet about our ~400 gem dependencies. We decided to tackle this problem by generating interface files (RBI) for each gem via runtime reflection. However, this turns out to not be as simple as it sounds; the flexible nature of Ruby allows gem authors to do many wild things that make this Hard. Come and hear about all the lessons that we learnt about runtime reflection in Ruby while building `tapioca`. ### Details - **Intro**: The need for generating RBI files - Static analysis and Sorbet’s limitation - Gems are black boxes as far as static analyzer is concerned - RBI format - **Reflection**: Ruby reflection APIs - How to do runtime reflection in Ruby - `Module#const_get`, `Module#constants`, `Module#instance_methods` and friends - `Method#source_location` - How to find a constant’s location? (Ruby 2.7 adds `const_source_location`) - **Bootstrapping**: Which constants do we start from? - Run Sorbet over gem source files to create a list of exported “constants” as seen statically. - Walk over the list of constants - **Reopening core classes**: Active Support and friends - How to detect if a gem is adding methods to core types? - How to tell which methods were added by which gem? - **Pitfalls and Solutions**: What to watch out for? - Pitfall: Gems overriding various base methods `Module#name`, `Kernel#class`, etc - Solution: `.bind(obj).call` idiom (Ruby 2.7 adds `bind_call`) - Pitfall: Private superclasses - Solution: Check superclasses for visibility and walk up the chain - Pitfall: Classes that end up being their own superclasses - Solution: Compare the resolved name of superclass and walk up the chain - Pitfall: Methods with invalid names (`define_method(“123”) {}`) - Solution: Enforce proper naming for generated methods - Surprise: What if a gem deletes a top-level type!? - **Shortcomings** - Cannot isolate changes to types to a particular gem - Cannot represent some Ruby constructs faithfully (like `Forwardable`) - **Conclusions and take aways** ### Pitch Ruby has one of the nicest reflection APIs across all languages, but the dynamic nature of the Ruby language allows gem authors to do wild things. This makes proper reflection and, in turn, interface generation very hard. This talk will present an overview of the Ruby reflection API and talk about what makes it so hard to do reflection correctly in the wild for arbitrary types exported from gems. For every challenge, solutions will be presented and discussed. The talk will also mention how Ruby is improving its APIs to make doing this kind of work easier, with the addition of `const_source_location` and `bind_call` in 2.7, for example. The speaker is the primary author of the open-source [`tapioca`](https://github.com/Shopify/tapioca) gem at Shopify and has had to deal with all this complexity to get everything working both correctly and with reasonable coverage.
Back to Speaker Directory