RBS est un langage permettant de décrire la structure des programmes Ruby. Vous pouvez écrire la définition d'une classe ou d'un module : méthodes définies dans la classe, variables d'instance et leurs types, et relations d'héritage/mix-in. Il permet également de déclarer des constantes et des variables globales.
Ce qui suit est un petit exemple de RBS pour une application 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
à partir de 2023.)>= 3.0
à partir de 2023.) Installez la gemme rbs
. $ gem install rbs
à partir de la ligne de commande ou ajoutez une ligne dans votre Gemfile
.
gem "rbs"
La gemme est livrée avec l'outil de ligne de commande rbs
pour démontrer ce qu'elle peut faire et aider à développer RBS.
$ rbs version
$ rbs list
$ rbs ancestors ::Object
$ rbs methods ::Object
$ rbs method Object then
Un utilisateur final de rbs
trouvera probablement rbs prototype
le plus utile. Cette commande génère des déclarations de signature standard pour les fichiers Ruby. Par exemple, disons que vous avez écrit le script Ruby ci-dessous.
# 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
L'exécution du prototype sur ce qui précède générera automatiquement
$ 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
Il imprime les signatures pour toutes les méthodes, classes, variables d'instance et constantes. Ceci n'est qu'un point de départ et vous devez modifier le résultat pour qu'il corresponde plus précisément à votre signature.
rbs prototype
propose trois options.
rb
génère uniquement à partir du code Ruby disponiblerbi
génère à partir de Sorbet RBIruntime
génère à partir de l'API d'exécution Il existe deux concepts importants, l'environnement et la définition .
Un environnement est un dictionnaire qui garde une trace de toutes les déclarations. Quelle est la déclaration associée à la classe String
? Un environnement vous donnera la réponse.
Une définition vous donne le détail de la classe. Quel est le type de valeur de retour de la méthode gsub
de la classe String
? La définition de la classe String
connaît la liste des méthodes qu'elle fournit et leurs types.
Ce qui suit est un petit code pour récupérer la définition de la méthode 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
et Struct
Voici une liste de quelques endroits où vous pouvez discuter avec les responsables actifs.
rbs
sur le serveur Ruby Discord.types
dans l'espace de travail Slack ruby-jp. Après avoir extrait le dépôt, exécutez bin/setup
pour installer les dépendances. Ensuite, exécutez bundle exec rake test
pour exécuter les tests. Vous pouvez également exécuter bin/console
pour une invite interactive qui vous permettra d'expérimenter.
Pour installer cette gemme sur votre machine locale, exécutez bundle exec rake install
. Pour publier une nouvelle version, mettez à jour le numéro de version dans version.rb
, puis exécutez bundle exec rake release
, qui créera une balise git pour la version, poussera les commits et les balises git, et poussera le fichier .gem
vers rubygems.org.
Les rapports de bogues et les demandes d'extraction sont les bienvenus sur GitHub à l'adresse https://github.com/ruby/rbs.