-
Notifications
You must be signed in to change notification settings - Fork 10
Syntax guide
# rbs_inline: enabled
magic comment is required to generate RBS from Ruby code.
# rbs_inline: enabled
class Foo
end
You can also use # rbs_inline: disabled
magic comment for --opt-out
options.
The class
syntax in Ruby is translated to class definition in RBS. Note that the class names and super class names must be constant syntax in Ruby.
class Foo
end
Generic classes can be defined with # @rbs generic
annotation.
# @rbs generic A -- Type of `a`
# @rbs generic unchecked in B < String -- Type of `b`
class Foo
end
The class definition generates the following RBS definition:
class Foo[A, unchecked in B < String]
end
The constant super class is supported. Generics is also supported by #[
annotation.
class Foo < String
end
class Bar < Array #[String]
end
# @rbs inherits
annotation allows specifying super class with RBS syntax, even if the super class syntax in Ruby is something unsupported.
# @rbs inherits Hash[String, Integer]
class Foo < Hash
end
# @rbs inherits Struct[String | Integer]
class Bar < Struct.new(:size, :name, keyword_init: true)
end
The module
syntax in Ruby is translated to a module definition in RBS. Note that the module name must be constant syntax in Ruby.
module Foo
end
Generics is supported with # @rbs generic
annotation, like class definition.
Module self type constraints can be defined with # @rbs module-self
annotation.
# @rbs module-self BasicObject
module Kernel
end
For method calls with blocks that defines modules/classes implicitly, we introduce @rbs class
and @rbs module
syntax.
module Foo
extend ActiveSupport::Concern
# @rbs module ClassMethods
class_methods do
# @rbs () -> Integer
def foo = 123
end
end
The @rbs module
and @rbs class
annotations accepts RBS syntax for opening modules/classes. end
is omitted.
Mixin method calls with constant syntax -- include
, prepend
, and extend
-- are translated to mixin syntax in RBS.
class Foo
include Foo
extend Enumerable #[Integer, void]
end
The #[
syntax allows mixing generic modules.
We have two syntaxes for type of methods.
This is more primitive syntax. It allows writing RBS method type embedded in Ruby code.
#: () -> String
def to_s
end
#: (?Regexp?) -> Enumerator[String, void]
#: (?Regexp?) { (String) -> void } -> void
def each_person(pattern = nil, &block)
end
Having multiple #:
syntax generates method definition with overloads.
You can also write method types after # @rbs
keyword.
# @rbs () -> String
def to_s
end
# @rbs (?Regexp?) -> Enumerator[String, void]
# | (?Regexp?) { (String) -> void } -> void
def each_person(pattern = nil, &block)
end
Note that the @rbs METHOD-TYPE
syntax allows writing method overloadings with |
s.
Here is the example of doc style syntax.
# @rbs size: Integer -- The size of the section in px
# @rbs optional: Integer -- Type of the optional parameter
# @rbs title: String -- Title of the section
# @rbs content: String -- Type of the optional keyword parameter
# @rbs *rest: String -- Type of the rest args
# @rbs **kwrest: untyped -- Type of the keyword rest args
# @rbs return: Section? -- Returns the new section or `nil`
def section(size, optional=123, title:, content: "Hello!", *rest, **kwrest)
end
You can write down type of parameters like # @rbs var: TYPE -- some comments
. The @rbs return: TYPE
defines the return type.
The block types can be defined with # @rbs &block:
annotations.
# @rbs &block: (?) -> untyped -- Block is required, but not clear what will be yielded
def foo(&block)
yield 1
yield 2, "true"
end
# @rbs &block: ? (?) -> untyped -- Block is optional
def bar(&block)
end
# @rbs &: (String) -> void -- It yields String
def baz
end
The variable names of *
, **
, and &
syntax are optional, as the omission is allowed in Ruby too.
# @rbs *: untyped
# @rbs **: String
# @rbs &: ? (String) -> bool
def foo(*, **) = nil
We also have #:
syntax at method definition which allows defining method return type.
def to_s #: String
end
The parse now handles parameter type declarations even with keywords. The only exception is return type, and the return
keyword should be escaped as !return
for the type of the parameter.
# @rbs yields: String
# @rbs skip: untyped
# @rbs !return: bool
def foo(return:, yields:, skip:) #: void
end
# @rbs override
annotation tells the method is overriding the super class definition.
# @rbs override
def foo(x, y)
end
This generates def foo: ...
. We need this annotation to avoid having parameters types and the return type untyped
, while we don't want to copy and paste the super method definition.
def self.foo
syntax inside a class/module definition is supported.
Other receivers nor singleton class definition syntax <<self
are not supported.
# @rbs %a{}
syntax allows giving annotations to methods.
# @rbs %a{pure} %a{another:annotation}
def to_s #: String
end
The standard attribute definition methods are supported -- attr_reader
, attr_writer
, and attr_accessor
.
class Foo
attr_reader :name #: String
attr_reader :size, :count #: Integer
end
Attribute names defined with symbol literal are supported. One attribute method call can have several names, but all of them will have the same type.
You can use # @rbs @var: Type
annotation.
class Foo
# @rbs @name: String -- Instance variable
# @rbs self.@all_names: Array[String] -- Instance variable of the class
end
Add #:
syntax to declare constant of a specific type. The gem infers some simple types for literals.
VERSION = "1.2.3"
Foo = [1,2,3].sample #: Integer
alias
syntax in Ruby code is detected and alias
declaration will be generated in RBS.
class Foo
def ==(other) #: bool
end
alias eql? ==
end
You may want to # @rbs skip
annotation to skip generating RBS definition.
# @rbs skip
class HiddenClass
end
class Foo
# @rbs skip
def hidden_method
end
end
We have # @rbs!
annotation for something not covered by the annotations.
class Person
include ActiveModel::Model
include ActiveModel::Attributes
attribute :id, :integer, default: 0
attribute :name, :string, default: ''
# @rbs!
# attr_accessor id (): Integer
#
# attr_accessor name (): String
end
-
# @rbs returns T
is deprecated. Use# @rbs return: T
. -
# @rbs yields: T
is deprecated. Use# @rbs &block: T
syntax. -
#::
is deprecated. Use#:
syntax.