Gemme Util
English explanations below. ⇓ Esplicacioun en prouvènçau dessouto.
Cette gemme regroupe un certain nombre de petits utilitaires visant à simplifier l’écriture de code en Ruby. Il n'y a pas de logique particulière dans ce qui y est réuni, si ce n’est que chaque classe correspond à une fonctionnalité répétitive à écrire, mais utile dans de nombreux codes plus spécialisés. Pour l’heure, les classes sont les suivantes (par ordre alphabétique).
Sauf mention contraire, toutes les classes sont contenues dans le module principal Util. Se reporter à la documentation (en anglais) pour une explication plus détaillée du fonctionnement de chaque classe.
→ Args et Opts
Cette classe sert à vérifier le type des arguments passés à une fonction et, au besoin, à remplacer un argument invalide par une valeur par défaut. La variante Opts est utilisée pour les dictionnaires d’options.
def creer_dict_entier cle, valeur
cle, valeur = Util::Args.check cle, Symbol, :def, valeur, Integer, nil
{ cle => valeur }
end
def initialize opts={}
@encodage, @corps, @hauteur_ligne = Util::Opts.check opts, \
:enc, String, 'UTF-8', :corps, Integer, 12, :hauteur, Float, 1.0
end
→ ConsoleLogger
Cette classe offre une interface simple pour écrire différents types de messages sur le terminal, mis en forme et avec des couleurs. Fortement configurable.
cl = ConsoleLogger.new e: { :stderr => true }
cl.warning 'Les erreurs seront affichées sur STDERR.'
# Message écrit en jaune
begin
texte = File.read 'secret.msg'
rescue Exception => e
msg = 'Impossible d’aller plus loin à cause de %E%, abandon.'
cl.error msg, 'E': e.
# Message écrit en rouge
end
→ Downloader
Une classe permettant de télécharger un fichier de manière sécurisée.
require 'oga' # Doit être requis par l’utilisateur, `Util` ne le fera pas
url = 'https://www.perdu.com/'
html = Util::Downloader.new(url).set_dest(Oga)
html.download # => Util::Result.ok
html.data.at_css('h1').text # 'Perdu sur l\'Internet ?'
url = 'https://gitlab.com/uploads/-/system/user/avatar/5582173/avatar.png'
Util::Downloader.new(url).set_name('guillel.png').set_force.download
→ I18n
Une classe permettant de faire de l’internationalisation basique. Ce n’est en rien un système complet prenant en charge le sens de lecture des langues ou les différentes manières de gérer le pluriel. Un code d’identification et une langue donnent une chaîne de caractères, rien de plus. Si vous avez besoin de quelque chose de plus complexe, il vaudra mieux vous tourner vers la gemme i18n de Rails, voire vers gettext.
Util::I18n << __FILE__
Util::I18n.set_default_language :prv
Util::I18n. 'bonjour' # 'Adiéu'
Util::I18n. 'bonjour', lang: :fra # 'Bonjour'
→ Lists
Un module qui regroupe des sous-modules représentant des listes utiles.
⇒ Lists::ISO639
Un module contenant les codes ISO 639. Pour l’instant, seule la classe P3 contenant les codes ISO 639-3 est disponible.
codes = Util::Lists::ISO639
puts codes::P3.from1 'fr' # :fre
puts codes::P3.exist? :prv # true
puts codes::P3.valid? :prv # false
→ Result
Une classe pour encapsuler un résultat et éviter les exceptions, similaire au Result de Rust ou OCaml.
class Num
attr_reader :contenu
def initialize num
@contenu = num.to_f
end
def self.ajouter premier, second
Util::Result.ok Num.new(premier.contenu + second.contenu)
end
def ajouter num
Util::Result.ok Num.new(@contenu + num.to_f)
end
def diviser denom
return Util::Result.err :div0, self if denom == 0
Util::Result.ok Num.new(@contenu / denom.to_f)
end
end
res = Num.new(42).ajouter(79) \
.bindm(:ajouter, 11) \
.bindm(:diviser, 12) \
.bindcm(:ajouter, Num.new(13)).value # 24
res = Num.new(42).ajouter(79) \
.bindm(:ajouter, 11) \
.bindm(:diviser, 0) \
.bindcm(:ajouter, Num.new(13)).error # :div0
→ Testing
Une classe pour simplifier l’écriture de tests unitaires. Là encore, on reste sur du basique. Pour quelque chose de plus complexe, on se tournera vers des environnements de test dédiés.
class MaClasse
def self.fonction arg
raise ArgumentError, 'Ce n’est pas un entier non signé.' unless arg.to_i >= 0
-arg.to_i
end
end
test = Util::Testing.new
test.register 'succes', [-12, -42] do ||
[MaClasse.fonction('12'), MaClasse.fonction(42.0)]
end
test.register 'succes-avec-resultat-implicite' do ||
MaClasse.fonction '12'
true
end
test.register 'echec-attendu', ArgumentError, 'signé' do ||
MaClasse.fonction -1
end
test.register 'mauvaise-raison', ArgumentError, 'signé' do ||
MaClasse.fonction
end
test.register 'mauvaise-exception', ArgumentError, 'signé' do ||
MonAutreClasse.fonction
end
test.run
→ YAML (module indépendant)
Une extension du module YAML de la bibliothèque standard, qui se contente d’ajouter une fonction from_file permettant de lire un fichier YAML tout en vérifiant qu’aucune erreur ne s’est produite.
Util gem
This gem groups together a number of small utilities that aim to make writing code in Ruby easier. There is no specific logic behind the collection, except that each class corresponds to a functionality that is repetitive to write, but useful in many more specialized codes. For now, the following classes are extant (in alphabetical order).
Unless specified otherwise, all classes are contained inside the Util main module. See the documentation for a more detailed explanation of how each class works.
→ Args and Opts
This class is used to typecheck the arguments provided to a function and, if needed, replace an invalid argument by a default value. The Opts variant is used for option hashes.
def create_integer_hash key, value
key, value = Util::Args.check key, Symbol, :def, value, Integer, nil
{ key => value }
end
def initialize opts={}
@encoding, @font_size, @line_height = Util::Opts.check opts, \
:enc, String, 'UTF-8', :size, Integer, 12, :height, Float, 1.0
end
→ ConsoleLogger
This class offers a simple interface to write different kinds of messages on the console, formatted and colored. Highly configurable.
cl = ConsoleLogger.new e: { :stderr => true }
cl.warning 'Errors will be logged on STDERR.'
# Message written in yellow
begin
text = File.read 'secret.msg'
rescue Exception => e
msg = 'Cannot go any further because of %E%, aborting.'
cl.error msg, 'E': e.
# Message written in red
end
→ Downloader
A class to safely download a file.
require 'oga' # Must be required by the user, `Util` will not do it
url = 'https://www.perdu.com/'
html = Util::Downloader.new(url).set_dest(Oga)
html.download # => Util::Result.ok
html.data.at_css('h1').text # 'Perdu sur l\'Internet ?'
url = 'https://gitlab.com/uploads/-/system/user/avatar/5582173/avatar.png'
Util::Downloader.new(url).set_name('guillel.png').set_force.download
→ I18n
A class to do some basic internationalization. It is in no way a full-fledged system that would take into account reading directions or different ways of pluralizing. An token and a language give a string, nothing more. If you need something more complex, you should rather use Rails i18n gem, or even gettext.
Util::I18n << __FILE__
Util::I18n.set_default_language :prv
Util::I18n. 'bonjour' # 'Adiéu'
Util::I18n. 'bonjour', lang: :fra # 'Bonjour'
→ Lists
A collection of submodules respresenting useful lists.
⇒ Lists::ISO639
A module containing ISO 639 codes. For now, the class P3 containing ISO 639-3 codes is the only one available.
codes = Util::Lists::ISO639
puts codes::P3.from1 'fr' # :fre
puts codes::P3.exist? :prv # true
puts codes::P3.valid? :prv # false
→ Result
A class to wrap a result and avoid exceptions, similar to Rust’s or OCaml’s Result.
class Num
attr_reader :content
def initialize num
@content = num.to_f
end
def self.add first, second
Util::Result.ok Num.new(premier.first + second.content)
end
def add num
Util::Result.ok Num.new(@content + num.to_f)
end
def divide denom
return Util::Result.err :div0, self if denom == 0
Util::Result.ok Num.new(@content / denom.to_f)
end
end
res = Num.new(42).add(79) \
.bindm(:add, 11) \
.bindm(:divide, 12) \
.bindcm(:add, Num.new(13)).value # 24
res = Num.new(42).add(79) \
.bindm(:add, 11) \
.bindm(:divide, 0) \
.bindcm(:add, Num.new(13)).error # :div0
→ Testing
A class to make writing unit tests easier. There again, it remains basic. For something more complex, better go with a dedicated testing framework.
class MyClass
def self.function arg
raise ArgumentError, 'Not an unsigned int.' unless arg.to_i >= 0
-arg.to_i
end
end
test = Util::Testing.new
test.register 'success', [-12, -42] do ||
[MyClass.function('12'), MyClass.function(42.0)]
end
test.register 'success-with-implicit-result' do ||
MyClass.function '12'
true
end
test.register 'expected-fail', ArgumentError, 'unsigned' do ||
MyClass.function -1
end
test.register 'wrong-reason', ArgumentError, 'unsigned' do ||
MyClass.function
end
test.register 'wrong-exception', ArgumentError, 'unsigned' do ||
MyOtherClass.function
end
test.run
→ YAML (module indépendant)
An extension to the standard library module YAML, that just adds a from_file function allowing to read a YAML file while checking that no error happened.
Gèmo Util
Aquesto gèmo recampo quauqui pichòtis utilita servènt à escriéure dóu code Ruby mai simplamen. I a pas gaire de lougico dins ço qu’i es reüni, à despart de que cado classo courrespond à quicon de repetitéu à escriéure, mai utile dins un mouloun de code mai especialisa. Aro, li classo soun li seguènto (alfabeticamen).
Sènso mencioun countràri, tòuti li classo soun countengudo dins lou moudule principau Util. Vèire la doucumentacioun pèr d’esclargimen sus coume marcho cado classo.
→ Args e Opts
Aquesto classo sèr à s’assegura dóu tipe dis argumen passa à-n-uno founcioun e, au besoun, à ramplaça un argumen invalide amé ’no valour pèr defaut. La varianto Opts s’uso pèr li diciounàri d’oupcioun.
def crea_dic_entie clau, valour
clau, valour = Util::Args.check clau, Symbol, :def, valour, Integer, nil
{ clau => valour }
end
def initialize oupc={}
@encoudage, @cors, @aussado_ligno = Util::Opts.check oupc, \
:enc, String, 'UTF-8', :cors, Integer, 12, :aussado, Float, 1.0
end
→ ConsoleLogger
Aquesto classo óufris uno interfàci simplo pèr escriéure divèrsi message sus lou terminau, mes en fourmo e acoulouri. Se pòu mai counfigura.
cl = ConsoleLogger.new e: { :stderr => true }
cl.warning 'Lis errour saran escricho sus STDERR.'
# Message escri en jaune
begin
text = File.read 'secret.msg'
rescue Exception => e
msg = 'Impoussible d’ana mai liuen à cause de %E%, abandoun.'
cl.error msg, 'E': e.
# Message escri en rouge
end
→ Downloader
Uno classo pèr telecarga un fiquié seguramen.
require 'oga' # Dèu èstre requist pèr l’usagié, `Util` lou fara pas
url = 'https://www.perdu.com/'
html = Util::Downloader.new(url).set_dest(Oga)
html.download # => Util::Result.ok
html.data.at_css('h1').text # 'Perdu sur l\'Internet ?'
url = 'https://gitlab.com/uploads/-/system/user/avatar/5582173/avatar.png'
Util::Downloader.new(url).set_name('guillel.png').set_force.download
→ I18n
Uno classo pèr faire de l’internaciounalisacioun elementàri. Es pas ges de sistèmo entié que tèn comte dóu sèns de leituro di lengo vo di biais diferènt de mena lou plurau. Un code d’identificacioun e uno lengo baion uno cadeno d’emprèsso, ges de mai. Se vous fai mestié d’agué quicon de mai coumplèisse, vaudra miés chausi la gèmo i18n de Rails, emai bessai gettext.
Util::I18n << __FILE__
Util::I18n.set_default_language :prv
Util::I18n. 'bonjour' # 'Adiéu'
Util::I18n. 'bonjour', lang: :fra # 'Bonjour'
→ Lists
Uno couleicioun de souto-moudule que represènton de tiero utile.
⇒ Lists::ISO639
Un moudule countenènt li code ISO 639. Aro, i a que la classo P3, que countèn li code ISO 639-3.
codes = Util::Lists::ISO639
puts codes::P3.from1 'fr' # :fre
puts codes::P3.exist? :prv # true
puts codes::P3.valid? :prv # false
→ Result
Uno classo pèr embala un resultat e s’engarda dis eicecioun, coume lou Result de Rust o OCaml.
class Num
attr_reader :countengu
def initialize num
@countengu = num.to_f
end
def self.apoundre premie, segound
Util::Result.ok Num.new(premie.countengu + segound.countengu)
end
def apoundre num
Util::Result.ok Num.new(@countengu + num.to_f)
end
def parti denoum
return Util::Result.err :div0, self if denoum == 0
Util::Result.ok Num.new(@countengu / denoum.to_f)
end
end
res = Num.new(42).apoundre(79) \
.bindm(:apoundre, 11) \
.bindm(:parti, 12) \
.bindcm(:apoundre, Num.new(13)).value # 24
res = Num.new(42).apoundre(79) \
.bindm(:apoundre, 11) \
.bindm(:parti, 0) \
.bindcm(:apoundre, Num.new(13)).error # :div0
→ Testing
Uno classo pèr assimpli l’escrituro d’assai unitàri. Aqui tambèn, demouro elementàri. Pèr quicon de mai coumplèisse, fau chausi un vertadier envirounamen d’assai.
class MaClasso
def self.founcioun arg
raise ArgumentError, 'Pas ges d’entié noun signa.' unless arg.to_i >= 0
-arg.to_i
end
end
assai = Util::Testing.new
assai.register 'reussido', [-12, -42] do ||
[MaClasso.founcioun('12'), MaClasso.founcioun(42.0)]
end
assai.register 'reussido-senso-resultat-espres' do ||
MaClasso.founcioun '12'
true
end
assai.register 'revirado-esperado', ArgumentError, 'signa' do ||
MaClasso.founcioun -1
end
assai.register 'marrido-encauso', ArgumentError, 'signa' do ||
MaClasso.founcioun
end
assai.register 'marrido-eicecioun', ArgumentError, 'signa' do ||
MounAutroClasso.founcioun
end
assai.run
→ YAML (moudule independènt)
Vèn espandi lou moudule YAML de la biblioutèco ourdinàrio, e fai ren de mai qu’apoundre uno founcioun from_file, que permet de legi un fiquié YAML en s’assegurant que i a pas agu d’errour.