Aus Linux-Magazin 03/2007

Workshop: Ruby-Module managen mit Rubygems

Für die Skriptsprache Ruby gibt es eine ganze Menge praktischer Module, von der einfachen Datenbankanbindung bis zum Webframework Rails. Rubygems hilft Ihnen dabei, sie zu installieren und wieder zu entfernen. Auch eigene Repositories können Sie damit leicht anlegen.

Perl wäre wohl kaum so erfolgreich, gäbe es nicht die berühmte Modulsammlung CPAN (Comprehensive Perl Archive Network). Für wirklich jeden Anwendungszweck findet sich dort ein passendes Modul, das sich über die CPAN-Shell noch dazu ziemlich einfach installieren lässt. Die Bedeutung eines einheitlichen, einfach zu benutzenden Modul-Repositories haben auch die Fans anderer Skriptsprachen erkannt und entwickeln für ihre Lieblingssprache ähnliche Lösungen. Für Ruby hat sich seit einiger Zeit Rubygems [1] als Quasistandard durchgesetzt. Dieser Artikel erklärt, wie Sie Rubygems verwenden.

Am besten von Hand

Im Vordergrund steht bei Rubygems die Verpackung einzelner Softwaremodule als so genannte Gems (Edelsteine), in denen alle nötigen Dateien vorhanden sind, die aber auch Abhängigkeiten und so weiter festlegen. Weil die meisten Gems aber auch auf einem zentralen Server liegen, wird daraus gleich eine komplette Infrastruktur für die Ruby-Softwareverteilung.

Manche Distributionen wie Debian und Ubuntu führen Rubygems als Paket, das sich mit »apt-get install rubygems« installieren lässt. Wer eine andere Distribution verwendet oder die neueste Rubygems-Version (seit Anfang Januar 0.9.1) installieren möchte, lädt am besten das Quellpaket von [2] herunter. Die Installation setzt die Pakete Rdoc und Irb voraus, die sich auf allen getesteten Systemen in den Repositories befinden.

Im einfachsten Fall führen Sie als Administrator im Rubygems-Verzeichnis den Befehl »ruby setup.rb« aus, der das Paket mit den Default-Einstellungen konfiguriert und anschließend die Dateien in das Ruby-Systemverzeichnis »/usr/lib/ruby/…« kopiert. Wollen Sie Rubygems an eine andere Stelle im Dateisystem installieren, zum Beispiel ins Homeverzeichnis, müssen Sie erst die Umgebungsvariablen »PREFIX«, »GEM_HOME« und »RUBYLIB« setzen und dann mit »ruby setup.rb –prefix= das Paket installieren. Mehr Details verrät Punkt 2.4 der Frequently Asked Questions [3].

Hat das ohne Fehler geklappt, finden Sie auf der Festplatte unter anderem das ausführbare Skript »gem«, mit dem Sie die einzelnen Gems installieren und wieder entfernen. Haben Sie Rubygems an einem Nicht-Standard-Ort installiert, müssen Sie den Pfad ausführbarer Programme »PATH« entsprechend anpassen, zum Beispiel »/bin« darin aufnehmen. Im Test führte die Nicht-Standard-Installation allerdings immer wieder zu unerklärlichen Fehlern und Warnungen, sodass sie nicht uneingeschränkt zu empfehlen ist.

Einfach zu bedienen

Ohne weitere Parameter ausgeführt gibt »gem« einen kurzen Hilfetext aus, der ausführlichere Hilfe-Optionen verrät. Interessant sind fürs Erste vor allem »gem help commands«, das alle verfügbaren Gem-Befehle auflistet, und »gem help examples«, das Anwendungsbeispiele der Kommandos aufführt. Im einfachsten Fall installiert »gem install Paketname« ein Ruby-Paket, zum Beispiel »gem install rails« das allseits beliebte Webframework Ruby on Rails [4].

Abbildung 1 zeigt, dass Gem auch abhängige Pakete installiert, den Benutzer aber jeweils um Erlaubnis fragt. Wollen Sie sich darum keine großen Gedanken machen, installiert Rubygems auf Wunsch alle Abhängigkeiten gleich automatisch. Dazu dient der Schalter »–include-dependencies« oder kurz »-y«. Eine Liste aller Installationsoptionen gibt »gem help install«. Das Gem-Kommando zum Entfernen installierter Pakete heißt »uninstall«. Die Pfade, in denen Rubygems seine Dateien ablegt, verrät der Befehl »environment« (Listing 1).

Abbildung 1: Installation von Ruby on Rails mit Hilfe von Rubygems. Der Paketmanager löst die Abhängigkeiten auf und präsentiert sie dem Benutzer.

Abbildung 1: Installation von Ruby on Rails mit Hilfe von Rubygems. Der Paketmanager löst die Abhängigkeiten auf und präsentiert sie dem Benutzer.

Listing 1:
Gem-Umgebung

01 $ gem environment
02 RubyGems Environment:
03   - VERSION: 0.9.1 (0.9.1)
04   - INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
05   - GEM PATH:
06      - /usr/lib/ruby/gems/1.8
07   - REMOTE SOURCES:
08      - http://gems.rubyforge.org

Eine Liste der installierten Gems liefert »gem list«. Wollen Sie die im Repository vorhandenen Gems anzeigen, verwenden Sie »gem list –remote« beziehungsweise »-r«. Als dieser Artikel entstand, waren das insgesamt mehr als 1200 Pakete. Um gezielt ein Paket zu finden, bietet Rubygems auch einen Suchbefehl. Zum Beispiel sucht »gem search –remote wiki« im Rubyforge-Repository nach Wiki-Paketen.

Dokumentation im Browser

Wie Abbildung 1 zeigt, installiert Rubygems per Default zu jedem Paket auch die Dokumentation. Um sie zu lesen, starten Sie den mitgelieferten Webserver »gem_server« und öffnen im Browser die Adresse »http://localhost:8808«. Dort finden Sie die installierten Pakete mit Links auf die installierte Rdoc-Dokumentation (Abbildung 2). Leider lässt sie häufig zu wünschen übrig: Oft fehlen allgemeine Hinweise zu Sinn und Verwendung eines Pakets, die Dokumentation beschränkt sich auf die reine Abbildung des API. Manchmal gibt es auch gar keine Informationen. Das ist natürlich nicht die Schuld von Rubygems, ärgerlich bleibt es dennoch.

Abbildung 2: Die Dokumentation der installierten Pakete zeigt Rubygems über den mitgelieferten »gem_server« im Browser.

Abbildung 2: Die Dokumentation der installierten Pakete zeigt Rubygems über den mitgelieferten »gem_server« im Browser.

Haben Sie das Rubygems-Paket zunächst von Hand installiert, können Sie es in Zukunft mit dem Gems-Befehl updaten. Bei aktuellen Rubygems-Versionen genügt dazu »gem update –system«. Weil installierte Gems sich in einem speziellen Unterverzeichnis befinden, das sich nicht im Ruby-Modulpfad befindet (siehe Listing 1), genügt es nicht, das Modul mit dem Befehl »require« einzubinden, wie es sonst in Ruby üblich ist. Stattdessen müssen Sie zuerst das Modul »rubygems« einbinden und dann erst das gewünschte Gem-Modul mit der Funktion »require_gem«.

In neueren Rubygems-Versionen ist dieser Befehl als obsolet gekennzeichnet, statt seiner soll nun eine Funktion »gem« verwendet werden. Leider scheint der Code in der allerneuesten Version 0.9.1 aber nicht perfekt zu funktionieren, wie eine Diskussion unter [comp.lang.ruby.gems-devel] auf [5] und entsprechende Bug-Tickets belegen.

Erfordert Ihr Ruby-Code eine bestimmte Version eines Moduls, können Sie diese mit der Require-Zeile spezifizieren:

gem 'activerecord', '>= 1.15.1'

Die Activerecord-Version muss in diesem Fall mindestens 1.15.1 sein, sonst meldet Ruby beim Ausführen des Skripts einen Rubygem Version Error. Wie man sieht, funktionieren Rubygems leider nicht völlig transparent, erfordern also Änderungen am Quellcode jedes Skripts, das sie verwendet.

Das ist wohl der größte Schwachpunkt des Rubygems-Konzepts. Damit zusammen hängt das Problem, dass Rubygems sich außerhalb des distributionseigenen Paketmanagements bewegen. Beide Punkte sind zum Beispiel den Debian-Entwicklern ein Dorn im Auge [6].

Gems anbieten

Trotz der erwähnten Schwächen ist und bleibt Rubygems mit seiner großen Zahl an Paketen das am weitesten verbreitete Ruby-Paketmanagementsystem. Wer nun seinen eigenen Rubygems-Server betreiben will, um zum Beispiel im lokalen Netz einer Gruppe von Ruby-Entwicklern stets aktuelle Module anzubieten, hat es leicht. Dazu genügt der mitgelieferte, bereits erwähnte Server »gem_server«. Haben Sie ihn zum Beispiel auf einer Server-Maschine mit der IP-Adresse 192.168.0.4 gestartet, greifen Sie von Clients folgendermaßen darauf zu:

gem list -r --source 192.168.0.4:8808

Der Server stellt automatisch alle installierten Gems bereit. Weil es auch architekturspezifische Gems gibt, zum Beispiel Win32-Gems, die sich naturgemäß nicht auf Linux installieren lassen, gibt es noch einen zweiten Weg, der mit nicht installierten Gems funktioniert. Zudem klappt das auch mit einem beliebigen Webserver, sodass Sie auf den Gem-Server verzichten können.

Dazu legen Sie nur ein Verzeichnis auf dem Server an, das die noch gepackten Gems enthält. Dann führen Sie »generate_yaml_index.rb« aus, das die nötigen Meta-Informationen im Yaml-Format erzeugt. Auf den Clients ist dann die entsprechende URL zu verwenden, die das von Ihnen angelegte Verzeichnis enthält. Detailliert führen die FAQ unter Punkt 4.2 noch einmal alle Schritte auf.

Möchten Sie sogar einen Schritt weiter gehen und eigene Gems anbieten, egal ob auf Ihrem oder dem Rubyforge-Server, stehen Ihnen mehrere Wege offen. Der klassische führt über die so genannte Gem-Spezifikation, eine Datei mit der Endung ».gemspec«, die ausführbaren Ruby-Code enthält. Haben Sie diese Datei fertig geschrieben, führen Sie den Befehl »gem build Paketname.gemspec« aus. Stimmen alle Angaben, finden Sie anschließend die fertige Gem-Paketdatei vor. Das Dateiformat ist nicht übermäßig ausführlich dokumentiert, eine kurze Referenz findet sich unter [7].

Am besten werfen Sie mal einen Blick auf die Gemspecs der installierten Pakete, die normalerweise in »/usr/lib/ruby/gems/1.8/specifications« liegen. Listing 2 zeigt das Gemspec-File einer kleinen Helferklasse für Postadressen.Auch ohne tief gehende Ruby-Kenntnisse dürften sich die Einträge ohne weiteres erschließen. Wichtig ist vor allem Zeile 9, die alle zu verpackenden Dateien auflistet. Zeile 5 mit der Autorequire-Direktive legt die Datei fest, die der Ruby-Interpreter lädt, wenn Skripte den Gem per Require-Anwendung einbinden.

Listing 2:
»adressen.gemspec«

01 Gem::Specification.new do |s|
02   s.name = "adressen"
03   s.version = "1.0.0"
04   s.date = "2007-01-17"
05   s.autorequire = "adressen"
06   s.add_dependency("rake")
07   s.summary = "Hilfsklassen fuer die Adressverwaltung"
08   s.email = "ofrommel@linux-magazin.de"
09   s.homepage = "https://www.linux-magazin.de"
10   s.description = "Enthält Klassen, die übliche Postadressen abbilden, inklusive Ausgabe"
11   s.has_rdoc = true
12   s.authors = ["Oliver Frommel"]
13   s.files = ["CHANGELOG", "README", "lib/adressen.rb"]
14 end

Zeile 6 führt dagegen die Pakete auf, von denen der eigene Gem abhängt. Sind sie unter »s.files« vorhanden, erzeugt »gem build adressen.gemspec« im gleichen Verzeichnis das Gem-Paket »adressen-1.0.0.gem«, das Sie anschließend mit »gem install ./adressen-1.0.0.gem« installieren können. Dummerweise löst Rubygems die Abhängigkeiten in diesem Fall nicht richtig auf und bemängelt das Fehlen von Rake nur, statt es einfach selbst zu installieren (Abbildung 3). Abhängigkeiten über verschiedene Repositories hinweg aufzulösen, steht erst für eine kommende Rubygems-Release auf dem Programm.

Abbildung 3: Ein eigenes Gem-Paket bauen und installieren. Leider installiert Rubygems in diesem Fall das geforderte Rake-Paket nicht automatisch.

Abbildung 3: Ein eigenes Gem-Paket bauen und installieren. Leider installiert Rubygems in diesem Fall das geforderte Rake-Paket nicht automatisch.

Ein paar Schwächen

Rubygems hat sich als De-facto-Standard für Paketverteilung und -installation mit der Skriptsprache Ruby etabliert. Wie häufig in der Open-Source-Szene gibt es auch hier konkurrierende Ansätze wie RPA (das Ruby Production Archive), das aber bei weitem nicht so verbreitet ist wie Rubygems. Leider scheinen die beiden Fraktionen durch grundlegend unterschiedliche Ansichten so gespalten, dass kaum mit einer Konvergenz der Lösungen zu rechnen ist.

Rubygems selbst funktioniert zwar im Prinzip gut, weist aber einige kleine Schwächen auf, die hoffentlich in Zukunft behoben werden. So ist es zum einen nicht besonders schnell, die Installation der knapp zehn Pakete für Rails dauert schon mal mehrere Minuten. Zum anderen könnten die Gems besser ins Paketmanagement der Distributionen eingebunden werden. Schließlich wäre auch eine transparente Verwendung der Gems ohne Sourcecode-Änderungen in eigenen Skripten wünschenswert.

Infos

[1] Rubygems-Homepage: [http://rubygems.org]

[2] Rubygems-Download: [http://rubyforge.org/frs/?group_id=126]

[3] FAQ zu Nicht-Standard-Installation: [http://rubygems.org/read/chapter/15]

[4] A. Röhrl, “Webprogrammierung mit Ruby und Rails”: Linux-Magazin 12/04, S. 100

[5] »comp.lang.ruby.gems.devel«: [http://news.gmane.org/gmane.comp.lang.ruby.gems.devel]

[6] Kritik der Debian-Entwickler an Rubygems: [http://pkg-ruby-extras.alioth.debian.org/rubygems.html]

[7] Gemspec-Referenz: [http://rubygems.org/read/chapter/20] – nur ein Test

Copyright © 2002 Linux New Media AG

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben