Využíváme knihoven instalovaný pomocí RubyGems
Knihovny, které nainstalujeme pomocí RubyGems, nejsou dostupné v klasické cestě rubyovských knihoven, a jejich volání v programech tedy nutně končí výjimkou LoadError
. Je tomu tak proto, aby bylo možno spravovat více verzí knihoven zároveň. Technicky se jedná o stejný systém jako sloty v distribuci Gentoo. Dejme tomu, že jsme si pomocí RubyGems nainstalovali jednu z knihoven pro protokol XMPP a chceme ji nyní použít ve svém programu, což může být dejme tomu třeba jabberovský bot. Nejprve ji zkusíme použít stejným způsobem, jako se to dělá se systémovými knihovnami:
#!/usr/bin/env ruby require "xmpp4r" ... 3485> ./gems.rb ./gems.rb:4:in `require': no such file to load -- xmpp4r (LoadError) from ./gems.rb:4
Jak vidíte, program opravdu skončil výše zmíněnou výjimkou. Nyní si to vyzkoušíme s načtením knihovny rubygems
pomocí metody require
:
#!/usr/bin/env ruby require "rubygems" require "xmpp4r" ... 3487> ./gems.rb 3488>
Jak je vidno, tato alternativa již funguje, ale za předpokladu, že nevíme, zda se bude volat knihovna z RubyGems či ze systému, je lepší to řešit jiným způsobem. Například volbou -rubygems
předanou interpretu Ruby:
#!/usr/bin/env ruby require "xmpp4r" ... 3490> ruby -rubygems gems.rb 3491>
Co se týče tohoto řešení, je na místě zmínit, že se nejedná vlastně o parametr rubygems
, nýbrž o parametr r
s hodnotou ubygems
. Ano, opravdu se knihovna jmenuje (také) ubygems
, ostatně podívejte se sami do svých rubyovských knihoven. V souboru ubygems.rb
naleznete volání knihovny rubygems
, jinými slovy se jedná o pouhou pomůcku, protože parametr rubygems
vypadá lépe nežli rrubygems
. Funguje ale obojí, jak si ostatně můžete vyzkoušet sami. Nicméně ani toto není nejlepší způsob, kdo by se s tím pořád psal, a proto sáhneme do svého /etc/profile
a exportujeme proměnnou RUBYOPT
:
#!/usr/bin/env ruby require "xmpp4r" ... 3493> export RUBYOPT="rubygems" 3494> ./gems.rb 3495>
Vidíte? Funguje to. Abych ale zmíněný příklad vysvětlil – opět se jedná o to samé, a sice o načtení knihovny rubygems
, tentokrát však automaticky při každém spuštění interpretu Ruby, zajištěné proměnnou prostředí RUBYOPT
.
Požadavek na určitou verzi knihovny
RubyGems umožňují načtení konkrétní verze knihovny. Jedná se o velmi sofistikovaný systém, který umožňuje nejenom načíst jistou knihovnu ve verzi kupříkladu 0.4, ale třeba také knihovnu v kterékoliv verzi vyjma 0.4.5, knihovnu ve verzi vyšší než 0.2 a podobně. Použití je jednoduché:
gem <knihovna> <verze>
… tedy například:
gem 'RedCloth', '> 3.0' # načti knihovnu RedCloth ve verzi vyšší než 3.0 gem 'rails', '= 0.9.3' # načti knihovnu rails právě ve verzi 0.9.3
Je na místě připomenout, že metoda gem očekává parametry třídy String a že verze rovná námi specifikované verzi se požaduje pomocí rovná se, nikoliv dvou rovná se vedle sebe, jak by programátoři spíše očekávali. Nenajde-li systém RubyGems požadovanou verzi, vyvolá výjimku.
Již několikrát jsem řekl, že RubyGems jsou skutečně sofistikovaný systém správy balíčků, a je tomu opravdu tak. Pokud vás náhodou dosud uvedený výčet možností nepřesvědčil, toto už opravdu musí. Může se stát, že naše podmínky pro specifikaci knihovny jsou velmi složité a že s prostou specifikací verze, verze větší než uvedenou a podobně si již nevystačíte. V tom případě vám nic nebrání zadat parametrů více, čím už můžete dosáhnout opravdu čehokoliv:
gem 'library', '>= 2.2.0', '< 3.0'
require_gem
, je to tak stále zmiňováno i v oficiální dokumentaci, nicméně je to zastaralé a měla by se na vše používat metoda gem
. Znak | Význam |
---|---|
= | požaduje konkrétní číslo verze |
!= | kteroukoliv jinou verzi než uvedenou |
> | větší než uvedenou |
< | menší než uvedenou |
>= | větší nebo rovnu uvedené |
<= | menší nebo rovnu uvedené |
~> | spíše větší než uvedená verze |
Tabulka možných specifikací verzí.
Software je živý organismus, neustále se vyvíjí. Požadované verze knihoven se mění a někdy by se dokonce hodilo, kdyby specifikace konkrétních verzí mohla být spíše v konfiguračním souboru, než přímo v kódu aplikace.
Konfigurační soubor config.yml
:
--- :gems: - ['RedCloth', '~> 3.0'] - ['rubyzip', '= 0.5.5']
Kód k načtení a zpracování konfiguračního souboru:
config = open("config.yml") do |file| YAML::load(file) end if config[:gems] require 'gemconfigure' Gem.configure(config[:gems]) end
Myslím, že zde není co vysvětlovat. V konfiguračním souboru specifikujeme výše uvedeným způsobem požadované verze, načteme knihovnu gemconfigure
a metodou Gem.configure
knihovny načteme. Jednoduché a efektivní, co víc si přát?
Příště
Zatímco dnes jsme se na RubyGems podívali jako programátoři, kteří právě potřebují využít knihovny distribuované skrze RubyGems, příště se (už opravdu) naučíme tvořit vlastní Gemy, naučíme se je podepisovat a dokonce si i ukážeme, jak je možné vytvořit a síťově zpřístupnit vlastní repozitář gemů.
Poznámka: některé ukázky byly přejaty z oficiální dokumentace k systému RubyGems.