for types • Matz didn't want it • Unclear if we can implement something without breaking compatibility • Didn't want to write types in string literals • sig("() -> void") • Meta programming
speakers: Array[Speaker] def initialize: (String title) -> void def first_speaker: () -> Speaker end class Talk attr_reader :title, :speakers def initialize(title) @title = title @speakers = [] end def first_speaker = speakers.first || raise end + + You have to edit two fi les to do one thing 🤔
when Ruby scripts under lib dir is changed • Steep detects the fi le changes and type checks automatically $ fswatch lib | xargs -n1 rbs-inline --output
RBS constructs for practical Ruby programs • Limited overloading and generic method, no interface, no type alias • Write RBS fi les if you need advanced features (or @rbs! annotation) • Concrete syntax matters • Review the method type syntax
• The texts after -- are comment for the parameter # @rbs string: String -- The content of the tag # @rbs attributes: Hash[Symbol, untyped] -- Attributes # @rbs returns String -- Returns the tag def tag(string, attributes) end
• The texts after -- are comment for the parameter # @rbs string: String -- The content of the tag # @rbs attributes: Hash[Symbol, untyped] -- Attributes # @rbs returns String -- Returns the tag def tag(string, attributes) end
• The texts after -- are comment for the parameter # @rbs string: String -- The content of the tag # @rbs attributes: Hash[Symbol, untyped] -- Attributes # @rbs returns String -- Returns the tag def tag(string, attributes) end
• The texts after -- are comment for the parameter # @rbs string: String -- The content of the tag # @rbs attributes: Hash[Symbol, untyped] -- Attributes # @rbs returns String -- Returns the tag def tag(string, attributes) end
• The texts after -- are comment for the parameter # @rbs string: String -- The content of the tag # @rbs attributes: Hash[Symbol, untyped] -- Attributes # @rbs returns String -- Returns the tag def tag(string, attributes) end
method • You can use anything based on the feature requirement, number of annotations you need, method type length, or size of the implementation def to_s #:: String end # @rbs returns String def to_s end
Hash[Symbol, untyped] ) #: String end def tag(string, attributes = {}) #: (String, ?Hash[Symbol, untyped]) -> String end Too wide Cryptic but not compact
syntax similar to YARD tags • The structure is same, but the actual syntax is di ff erent • We need more annotations other than @param and @returns • The type syntax is di ff erent from RBS # @param text [String, nil] # @param size [Integer] Size of it # @returns [String] <span> tag with style def font_size(text, size:) end # @rbs text: String? # @rbs size: Integer -- Si # @rbs returns String -- < def font_size(text, size:) end
compatible with YARD syntax • Passing --tag option to yardoc will ignore all RBS annotations • We can develop a YARD plugin that handles @rbs annotations [warn]: Unknown tag @rbs in file `lib/foo.rb` near line 3
syntax, before implementing it in rbs-gem • I already heard some requests: • @sig instead of @rbs • Writing method types immediately after # @rbs instead of #:: • @rbs return: T instead of @rbs returns T Approved
in Ruby code • It allows coding without switching between fi les • It gives more context when you are reviewing changes on your browser • Install rbs-inline gem to test it today • Catch me if you have any feedback/ideas/concerns • Small meeting with RBS folks at hack space during afternoon break