The presentation slides from RubyKaigi2022.
See also https://rubykaigi.org/2022/presentations/_ksss_.html
RBS generationframework usingRack architecture
View Slide
ksssYuki KuriharaREADYFOR, inc.From KOKA(ߕլ)in SHIGA
Logic model
ImpactHappyHacking
Outcome TypeEverywhereHH
Outputsin long AutoGenerationType FileTE
OutputsIn shortImplementationMarketingAGT
Implementation
IssuesNeeds a lot of TypeNeeds accuracyNeeds expandabilityNeeds flexibility
TracePoint TracePoint.new(:call) do |tp|args = tp.parameters.to_h do |op, name|b = tp.binding[name, b.local_variable_get(name).dup]endp [tp.self, args]end.enable(target: target) dorequire '...'end
Needs aNew ModelLoadBeforeAfterFeature
RackArchitecture
use Middleware1use Middleware2use Middleware3run App.newRack Architecture
use Middleware1use Middleware2use Middleware3run -> {require 'library'}Use case for Library
require 'library'use Middleware1use Middleware2use Middleware3run -> {Rails.application.eager_load!}Use case for Application
Sponsored by
New Product
OrthosesIUUQTHJUIVCDPNLTTTPSUIPTFTIUUQTFOXJLJQFEJBPSHXJLJ0SUIPUJDT
Rack Orthosesclass Middlewaredef initialize(app)@app = appenddef call(env)@app.call(env)endendclass Middlewaredef initialize(loader)@loader = loaderenddef call@loader.callendend
Storestore = @loader.callpp store#=> {"Foo" => #,"Bar::Baz" => #}
Contentstore = @loader.callstore["Foo"] << "def foo: () -> int"store["Foo"] << "alias bar foo"store["Foo"] << "include Baz"
CallTracerfoo = CallTracer.newstore = foo.trace(Foo.method(:foo)) do@loader.callendfoo.captures.each do |capture|capture.method.receivercapture.argument[:name]end
CallTracer::Lazyfoo = CallTracer::Lazy.newstore = foo.trace('Foo#foo')) do@loader.callendfoo.captures.each do |capture|capture.method.receivercapture.argument[:name]end
Builder exampleOrthoses::Builder.new douse Orthoses::CreateFileByNameuse Orthoses::Mid, option: trueuse Orthoses::Tap do |store|store["Foo"] << "def foo: () -> void"enduse Orthoses::Mixinrun -> { require '...' }end
Middleware Examplemodule Orthosesclass Middef initialize(loader, option: false)@loader = loader@option = optionenddef callfoo = Orthoses::CallTracer::Lazy.newstore = foo.trace('Foo#foo') do@loader.callendfoo.captures.each do |capture|mod = capture.method.receivername = Utils.module_name(mod) or nextstore[name] << "def bar: () -> void"endstoreend
Nest to LineVTFVTFVTF
Middlewares•include, extend and prepend•attr_accessor, attr_writer and attr_reader•ObjectSpace•Constants•Tap and PP•RBS prototype
Middlewares•Load RBS•Filter•Create file by name•Autoload•DelegateClass
Orthoses-rails for Application•has_many, has_one and belongs_to•enum•delegated_type•scope•has_secure_passwordIUUQTHJUIVCDPNLTTTPSUIPTFTSBJMT
Orthoses-rails for gems•TimeWithZone•railties•delegate•class_attribute, mattr_accessorIUUQTHJUIVCDPNLTTTPSUIPTFTSBJMT
You can create extension gems•orthoses-yard•orthoses-typeprof•orthoses-rolify
Feature tasks•gem_rbs_collection•Support Rails Application•Usability•Newcomers
Special ThanksQPDLF LP
Happy Hacking