RBS es un lenguaje para describir la estructura de programas Ruby. Puede escribir la definición de una clase o módulo: métodos definidos en la clase, variables de instancia y sus tipos, y relaciones de herencia/mezcla. También permite declarar constantes y variables globales.
El siguiente es un pequeño ejemplo de RBS para una aplicación de chat.
module ChatApp
VERSION: String
class User
attr_reader login: String
attr_reader email: String
def initialize : (login: String, email: String) -> void
end
class Bot
attr_reader name: String
attr_reader email: String
attr_reader owner: User
def initialize : (name: String, owner: User) -> void
end
class Message
attr_reader id: String
attr_reader string: String
attr_reader from: User | Bot # `|` means union types: `#from` can be `User` or `Bot`
attr_reader reply_to: Message? # `?` means optional type: `#reply_to` can be `nil`
def initialize : (from: User | Bot, string: String) -> void
def reply : (from: User | Bot, string: String) -> Message
end
class Channel
attr_reader name: String
attr_reader messages: Array[Message]
attr_reader users: Array[User]
attr_reader bots: Array[Bot]
def initialize : (name: String) -> void
def each_member : () { (User | Bot) -> void } -> void # `{` and `}` means block.
| () -> Enumerator[User | Bot, void ] # Method can be overloaded.
end
end
3.2
a partir de 2023.)>= 3.0
a partir de 2023.) Instale la gema rbs
. $ gem install rbs
desde la línea de comando o agrega una línea en tu Gemfile
.
gem "rbs"
La gema se envía con la herramienta de línea de comandos rbs
para demostrar lo que puede hacer y ayudar a desarrollar RBS.
$ rbs version
$ rbs list
$ rbs ancestors ::Object
$ rbs methods ::Object
$ rbs method Object then
Un usuario final de rbs
probablemente encontrará el rbs prototype
más útil. Este comando genera declaraciones de firma repetitivas para archivos Ruby. Por ejemplo, digamos que ha escrito el siguiente script Ruby.
# person.rb
class Person
attr_reader :name
attr_reader :contacts
def initialize ( name : )
@name = name
@contacts = [ ]
end
def speak
"I'm #{ @name } and I love Ruby!"
end
end
La ejecución del prototipo en lo anterior generará automáticamente
$ rbs prototype rb person.rb
class Person
@name: untyped
@contacts: untyped
attr_reader name: untyped
attr_reader contacts: untyped
def initialize: (name: untyped) -> void
def speak: () -> ::String
end
Imprime firmas para todos los métodos, clases, variables de instancia y constantes. Este es solo un punto de partida y debe editar el resultado para que coincida con su firma con mayor precisión.
rbs prototype
ofrece tres opciones.
rb
genera solo a partir del código Ruby disponiblerbi
genera desde Sorbet RBIruntime
se genera a partir de la API de tiempo de ejecución. Hay dos conceptos importantes, entorno y definición .
Un entorno es un diccionario que realiza un seguimiento de todas las declaraciones. ¿Cuál es la declaración asociada con la clase String
? Un entorno te dará la respuesta.
Una definición te da el detalle de la clase. ¿Cuál es el tipo de valor de retorno del método gsub
de la clase String
? La definición de la clase String
conoce la lista de métodos que proporciona y sus tipos.
El siguiente es un pequeño código para recuperar la definición del método String#gsub
.
require "rbs"
loader = RBS :: EnvironmentLoader . new ( )
# loader.add(path: Pathname("sig")) # Load .rbs files from `sig` directory
# loader.add(library: "pathname") # Load pathname library
environment = RBS :: Environment . from_loader ( loader ) . resolve_type_names
# ::String
string = RBS :: TypeName . new ( name : :String , namespace : RBS :: Namespace . root )
# Class declaration for ::String
decl = environment . class_decls [ string ]
# Builder provides the translation from `declaration` to `definition`
builder = RBS :: DefinitionBuilder . new ( env : environment )
# Definition of instance of String
instance = builder . build_instance ( string )
# Print the types of `gsub` method:
puts instance . methods [ :gsub ] . method_types . join ( " n " )
# Outputs =>
# (::Regexp | ::string pattern, ::string replacement) -> ::String
# (::Regexp | ::string pattern, ::Hash[::String, ::String] hash) -> ::String
# (::Regexp | ::string pattern) { (::String match) -> ::_ToS } -> ::String
# (::Regexp | ::string pattern) -> ::Enumerator[::String, self]
# Definition of singleton of String
singleton = builder . build_singleton ( string )
# No `gsub` method for String singleton
puts singleton . methods [ :gsub ]
Data
y Struct
Aquí hay una lista de algunos lugares donde puede hablar con mantenedores activos.
rbs
en el servidor Ruby Discord.types
en el espacio de trabajo ruby-jp Slack. Después de revisar el repositorio, ejecute bin/setup
para instalar las dependencias. Luego, ejecute bundle exec rake test
para ejecutar las pruebas. También puede ejecutar bin/console
para obtener un mensaje interactivo que le permitirá experimentar.
Para instalar esta joya en su máquina local, ejecute bundle exec rake install
. Para lanzar una nueva versión, actualice el número de versión en version.rb
y luego ejecute bundle exec rake release
, que creará una etiqueta git para la versión, enviará confirmaciones y etiquetas de git y enviará el archivo .gem
a rubygems.org.
Los informes de errores y las solicitudes de extracción son bienvenidos en GitHub en https://github.com/ruby/rbs.