Încărcarea automată a fișierelor Ruby cu Zeitwerk
- 3 minute de citit
- 6 exemple de cod în Ruby
Disponibil și în English
Pe această pagină
Introducere
Salut tuturor!
Pe când experimentam cu limbajul de programare Ruby în timp ce construiam o aplicație Rails, am dat peste Zeitwerk, o bibliotecă ce încarcă automat toate fișierele tale Ruby, și am vrut să scriu despre ea.
Ideea principală din spatele bibliotecii este că proiectul tău trebuie să respecte o anumită structură de fișiere, iar
biblioteca va încărca apoi toate fișierele Ruby, eliminând nevoia de a scrie require_relative 'x'. Acest lucru este
util deoarece păstrează codul structurat într-un mod opinionat și economisește câteva apăsări de taste la importul
fișierelor.
Am fost nedumerit la început când am răsfoit codul sursă al Gitlab și nu am văzut nicio instrucțiune de import, iar explicația este că ei folosesc Rails și Zeitwerk.
Utilizare
Pentru a folosi biblioteca, proiectul tău trebuie să respecte următoarea structură de directoare:
lib/my_gem.rb -> MyGemlib/my_gem/foo.rb -> MyGem::Foolib/my_gem/bar_baz.rb -> MyGem::BarBazlib/my_gem/woo/zoo.rb -> MyGem::Woo::ZooPoți, de asemenea, să o ajustezi fin prin colapsarea directoarelor, ignorarea unor directoare sau adăugarea de
inflexiuni.
(ex: unicredit.rb devine UniCredit; fără inflexiuni ar fi C cu literă mică)
Odată ce ai această structură, o poți instala scriind bundle add zeitwerk, apoi tot ce trebuie să faci este să
scrii niște cod standard (boilerplate) pentru a o configura.
Aplicație
Dacă scrii o aplicație, atunci poți apela biblioteca în fișierul principal, specificând directoarele pe care Zeitwerk ar trebui să le încarce.
require "zeitwerk"# Notă: nu există require_relative "huffman" deoarece Zeitwerk l-a încărcat automat.def main huffman = Huffman.new("huffman.md") content = huffman.encode print content.leftendif __FILE__ == $0 # Sunt necesare doar trei linii de cod loader = Zeitwerk::Loader.new loader.push_dir(File.expand_path("./lib")) loader.setup mainendStructura acestui proiect de aplicație arată astfel:
├── Gemfile├── Gemfile.lock├── huffman.md├── lib│ ├── huffman│ │ └── base_exception.rb│ ├── huffman.rb│ └── tree│ ├── base_node.rb│ ├── internal_node.rb│ └── leaf_node.rb├── main.rb # Fișierul principal, punctul de intrare├── Rakefile.rb└── test └── huffman_test.rbAtât este tot.
Gem (bibliotecă)
Când scrii o gem de bibliotecă, poți folosi Zeitwerk::Loader.for_gem. În gem-ul meu ExtrasDeCont am următorul punct
de intrare:
# frozen_string_literal: truerequire 'zeitwerk'loader = Zeitwerk::Loader.for_gemloader.inflector.inflect( "unicredit" => "UniCredit")loader.setup# Modulul ExtrasDeCont conține utilitare pentru analizarea extraselor de cont bancare.module ExtrasDeCont # Harta băncilor suportate (simbol → clasa de reguli) BANK_RULES = { brd: ExtrasDeCont::Rules::Brd, ing: ExtrasDeCont::Rules::Ing, revolut: ExtrasDeCont::Rules::Revolut, unicredit: ExtrasDeCont::Rules::UniCredit }.freeze class << self # Analizează un extras de cont bancar în format PDF și returnează tranzacțiile structurate. # # @param file [String, Pathname, IO] calea către fișierul PDF sau un obiect de tip IO # @param bank [Symbol] identificatorul băncii (:unicredit, :revolut, etc.) # @return [Array<ExtrasDeCont::Transaction>] # @raise [ArgumentError] dacă banca nu este suportată def parse(file, bank:) rule_class = BANK_RULES[bank] raise ArgumentError, "Unsupported bank: #{bank}. Supported banks: #{BANK_RULES.keys.join(", ")}" unless rule_class p = ExtrasDeCont::Parser.new(file) p.parse_with(rule_class.new) end endendloader.eager_loadObservă că am adăugat această inflexiune pentru ca unicredit.rb să se refere la UniCredit.
loader.inflector.inflect( "unicredit" => "UniCredit")În plus, structura de fișiere a gem-ului arată astfel:
.├── AGENTS.md├── bin│ └── example.rb├── changelog.md├── diagram.md├── entities.json├── extras_de_cont.gemspec├── Gemfile├── Gemfile.lock├── lib│ ├── extras_de_cont│ │ ├── parser.rb│ │ ├── rules│ │ │ ├── base.rb│ │ │ ├── brd.rb│ │ │ ├── ing.rb│ │ │ ├── revolut.rb│ │ │ └── unicredit.rb│ │ └── transaction.rb│ └── extras_de_cont.rb├── LICENSE├── mempalace.yaml├── opencode.json├── pkg│ ├── extras_de_cont-1.0.2.gem│ ├── extras_de_cont-1.1.0.gem│ ├── extras_de_cont-1.2.0.gem│ ├── extras_de_cont-1.3.0.gem│ └── extras_de_cont-1.4.0.gem├── Rakefile├── README.md├── sig│ └── extras_de_cont│ ├── extras_de_cont.rbs│ ├── parser.rbs│ ├── rules│ │ ├── base.rbs│ │ └── brd.rbs│ └── transaction.rbs└── test └── extras_de_cont └── rules ├── brd_rule_test.rb ├── ing_rule_test.rb ├── revolut_rule_test.rb └── unicredit_rule_test.rb12 directories, 35 filesConcluzie
Zeitwerk este un gem Ruby util care elimină nevoia de a require manual fișierele. Dacă răsfoiești niște cod Ruby și
toate require_relative lipsesc, atunci proiectul folosește probabil Zeitwerk.
Pentru ca Zeitwerk să funcționeze, va trebui să ai o anumită structură de directoare, dar Zeitwerk este foarte personalizabil.
Mulțumesc pentru lectură!