Programmierung in Ruby

Der Leitfaden der Pragmatischen Programmierer

Einführung



Dieses Buch ist eine Anleitung und eine Referenz für die Programmiersprache Ruby. Benutze Ruby und du wirst besseren Code schreiben, produktiver sein und am Programieren mehr Spaß haben.

Das sind dicke Worte, aber wir sind der Überzeugung, dass du nach der Lektüre dieses Buches auch so denken wirst. Und wir haben die Erfahrung im Rücken, die uns zu dieser Überzeugng stehen lässt.

Als Pragmatische Programmierer haben wir viele, viele Sprachen ausprobiert auf der Suche nach Mitteln, die uns das Leben einfacher machen, die uns helfen unseren Job besser zu machen. Bis jetzt wurden wir allerdings von den Sprachen, die wir benutzten, immer nur frustriert.

Unser Job ist es, Probleme zu lösen, nicht den Compiler mit kleinen Häppchen zu füttern, also mögen wir Sprachen, die sich uns anpassen, ohne willkürliche, einschränkende Regeln. Wir brauchen Klarheit, damit unser Code für sich selber spricht. Wir schätzen Präzision und die Möglichkeit, das Nötige akkurat und effizient im Code auszudrücken. Je weniger Code wir schreiben, desto weniger kann auch schiefgehen. (Und unsere Handgelenke und Finger sind auch dankbar.)

Wir möchten so produktiv wie möglich sein, also soll unser Code gleich beim ersten Mal laufen; Zeit, die man beim Debuggen verbringt, ist gestohlene Entwicklungszeit. Es ist auch hilfreich, wenn wir den Code gleich beim Schreiben ausprobieren können; wenn man auf einen zweistündigen Make-Zyklus warten muss, könnte man ja gleich Karten spielen gehen und seine Arbeit als Batch kompilieren lassen.

Wir wollen eine Sprache, die auf einem hohen Level der Abstraktion funktioniert. Je höher dieser Sprachlevel ist, desto weniger Zeit brauchen wir, um unsere Vorstellungen in den Code zu transformieren.

Als wir Ruby entdeckten, erkannten wir, dass wir das gefunden hatten, was wir suchten. Mehr als alle anderen Sprachen, mit denen wir gearbeitet haben, kommt Ruby einem nicht in die Quere. Man kann sich auf das anstehende Problem konzentrieren, anstatt sich mit Compiler- oder Sprach-Eigenheiten herumzuplagen. Darum kann Ruby einem helfen, ein besserer Programmierer zu werden: Man hast die Chance, seine Zeit mit dem Lösen von Benutzerproblemen zu verbringen, nicht von Compilerproblemen.

Ruby funkelt

Nimm eine richtig objekt-orientierte Sprache, etwa Smalltalk. Schmeiß die ungewöhnliche Syntax raus und benutze einen etwas konventionelleren, datei-basierten Quell-Code. Nun füge ein gutes Maß an Flexibilität und Komfort solcher Sprachen wie Python oder Perl hinzu.

Das alles zusammen ergibt Ruby.

OO-Liebhaber werden eine Menge schöner Sachen in Ruby finden: Sachen wie reine Objekt-Orientiertheit (alles ist ein Objekt), Metaklassen, Closures (der Übersetzer: was auch immer das sein mag), Iteratoren und allgegenwärtige verschiedenartige Colllections. Smalltalk-Programmierer werden sich wie zuhause fühlen (und C++ und Java-Programmierer werden Neid fühlen).

Gleichzeitig werden Perl- und Python-Zauberer viele ihrer geliebten Eigenheiten finden: volle Unterstützung für reguläre Ausdrücke, enge Anbindung an das darunter liegende Betriebssystem, komfortable Abkürzungen und dynamische Auswertung.

Ruby kann man einfach lernen. Die üblichen, täglichen Aufgaben sind einfach zu kodieren und wenn man es getan hat, sind sie leicht zu warten und zu erweitern. Anscheinend schwierige Sachen stellen sich als doch nicht so schwierig heraus. Ruby verfolgt das Prinzip der geringsten Überraschung --- die Dinge funktionieren so, wie man es von ihnen erwartet, mit wenigen Spezialfällen oder Ausnahmen. Und das macht wirklich den Unterschied aus, wenn man programmiert.

Wir bezeichnen Ruby als transparente Sprache. Damit meinen wir, dass Ruby die Lösungen, die man schreibt, nicht verschleiert hinter einer Masse von Syntax und der Notwendigkeit, sich durch Berge von Support-Code zu wühlen, nur um einfachste Dinge fertig zu bekommen. Mit Ruby schreibt man Programme dicht am Problem entlang. Statt nur dauernd die Konzepte deiner Ideen und Designs an die Niederungen der meisten anderen Progrmmiersprache anzupassen, kann man sie in Ruby direkter ausdrücken und eleganter. Das bedeutet, man programmiert schneller. Das bedeutet aber auch, das das Programm lesbar und wartbar bleibt.

Beim Arbeiten mit Ruby sind wir immer wieder erstaunt, wieviel Code wir in nur einer Sitzung schreiben können; Code, der gleich beim ersten Mal funktioniert. Es gibt nur wenige Syntax-Fehler, keine Typ-Verletzungen und viel weniger Bugs als üblich. Keine lästigen Semikolons, die man mechanisch ans Ende jeder Zeile zu setzen hat. Keine mühevollen Typdeklarationen, die man synchron halten muss (insbesondere bei mehreren verschiedenen Dateien). Keine eigentlich überflüssigen Wörter, nur um den Compiler bei Laune zu halten. Kein fehleranfälliger Rahmen-Code.

Warum sollte man also Ruby lernen? Wir denken, es hilft einem, besser zu programmieren. Es hilft einem, sich auf das anstehende Problem zu konzentrieren, mit weniger Ablenkungen. Es macht einem das Leben einfacher.

Was für eine Sorte Sprache ist Ruby?

Früher war die Unterscheidung der Sprachen einfach: sie wurden entweder kompiliert wie C oder Fortran oder interpretiert wie BASIC. Kompilierte Sprachen lieferten Geschwindigkeit und direkten Zugriff auf niedriger Ebene, interpretierte Sprachen waren abstrakter aber langsamer.

Die Zeiten ändern sich und die Dinge sind nicht mehr ganz so einfach. Einige Sprachentwickler nennen ihre Erfindungen ``Script-Sprachen''. Damit meinen sie wohl, dass ihre Sprachen interpretiert werden und dabei Batch-Dateien und Shell-Scripte ersetzen können und somit das Veralten von anderen Programmen und des darunter liegenden Betriebssystems beeinflussen. Perl, TCL und Python werden Script-Sprachen genannt.

Was genau bedeutet nun Script-Sprache? Ehrlich gesagt wissen wir nicht, ob so eine Unterscheidung überhaupt sinnvoll ist. In Ruby kann man alle Merkmale des Betriebssystems nutzen. Man kann die gleichen Sachen wie in Perl oder Python machen aber man kann es sauberer machen. Ansonsten ist Ruby grundsätzlich anders. Es ist jedenfalls eine echte Programmiersprache, mit starken theoretischen Wurzeln und einer eleganten leichtgewichtigen Syntax. Man kann einen Haufen ``Skripte'' mit Ruby zusammenhacken, aber wahrscheinlich wird man das bleiben lassen. Stattdessen wird man dahin geführt, eine Lösung zu entwerfen, ein Programm zu produzieren, das leicht zu verstehen ist, einfach zu warten und in Zukunft erweiterbar und wieder verwertbar.

Obwohl wir Ruby auch für Scripting-Aufgaben genutzt haben, benutzen wir es doch meistens als Programmiersprache für allgemeine Aufgaben. Wir haben damit GUI-Anwendungen (Graphical User Interface - Grafische Benutzer-Schnittstele) und Middle-Tier-Server Prozesse geschrieben und wir benutzen es, um große Teile dieses Buches zu formatieren. Andere Leute haben damit ihre Server und Datenbanken gemanaged. Ruby bedient Web-Seiten, verbindet sie mit Datenbanken und erzeugt dynamische Inhalte. Es gibt Leute, die schreiben damit künstliche Intelligenzen und lernfähige Programme und mindestens eine Person untersucht damit die natürliche Evolution. Ruby ist ebenso in der experimentellen Mathematik zuhause und überall auf der Welt werden unterschiedliche Anwendungen damit verbunden. Es ist tatsächlich eine Sprache, um damit Lösungen auf einem weiten Feld von Problemen zu generieren.

Ist Ruby was für mich?

Ruby ist nicht das Allheilmittel für alle Probleme des Prgrammierers. Es wird immer Gelegenheiten geben, wo man eine spezielle Sprache braucht: Die Umgebung kann das vorgeben, man braucht spezielle Bubliotheken, Performance ist wichtig oder es ist einfach eine Sache der Übung. Wir haben Sprachen wie Java oder C++ nicht völlig aufgegeben (obwohl wir an manchen Tagen wünschten, wir könnten es).

Wie dem auch immer sei, Ruby ist wahrscheinlich doch in größerem Maße anwendbar, als man denkt. Ruby ist einfach zu erweitern, sowohl von innen heraus als auch durch Hinzu-Linken einer externen Bibliothek. Es ist auf zahlreichen Plattformen einsetzbar. Es ist relativ leichtgewichtig und moderat beim Verbrauch von Systemresourcen. Und es ist leicht erlernbar; wir kennen Leute, die Ruby-Code in Produktions-Systeme eingebaut haben, nachdem sie dieses Buch erst einen Tag hatten. Wir haben mit Ruby Teile eines X11-Window-Managers implementiert, eine Aufgabe, für die man normalerweise harten C-Code nehmen würde. Ruby war besser und half uns Code in Stunden zu schreiben, für den wir sonst Tage gebraucht hätten.

Wenn man erstmal mit Ruby vertraut ist, wird man - so denken wir - es immer wieder als Sprache der Wahl benutzen.

Warum haben wir dieses Buch geschrieben?

Als wir gerade mit dem Buch The Pragmatic Programmer fertig waren, als unsere Familien wieder anfingen mit uns zu sprechen, da plötzlich fühlten wir das Bedürfnis, ein weiteres Bch zu schreiben. Warum? Wir vermuten, es hat etwas mit missionarischem Eifer zu tun.

Ruby wurde von Yukihiro Matsumoto (Matz) in Japan erfunden. Seit 1995 ist seine Popularitätsrate in Japan erstaunlich gestiegen; es gibt Gerüchte, dass Ruby in Japan populärer ist als Python. Aber bis jetzt ist vieles an detailierter Dokumentation auf Japanisch. Ruby ist eher keine Sprache, über die man so stolpert.

Wir wollten die Kunde verbreiten, damit mehr Leute auch außerhalb Japans Ruby benutzen und sich an den Vorteilen erfreuen können, deshalb entschieden wir uns, Ruby in Englisch zu dokumentieren. Und was als kleines Projekt begann, wuchs und wuchs und...

Ruby Versionen

Dieses Buch dokumentiert Version 1.6 von Ruby, die im September 2000 herauskam.

Die Versions-Nummerierung von Ruby folgt dem selben Schema wie bei vielen anderen Open-Source-Projekten. Releases mit geraden Unterversions-Nummern (1.0, 1.2, 1.4 und so weiter) sind stabile öffentliche Releases. Diese Releases werden auch vorgepackt und auf verschiedenen Ruby-Web-Seiten zur Verfügung gestellt.

Entwickler-Versionen der Software haben ungerade Subversions-Nummern wie 1.1 und 1.3. Diese muss man downloaden und selber kompilieren, wie wird im Kasten auf Seite xxvii beschrieben.

Ruby installieren

Man kann Ruby von ftp://ftp.netlab.co.jp/pub/lang/ruby beziehen oder von den Mirror-Seiten von Seite 532 im Anhang C. Dort findet man die neuste stabile Release, zusammen mit verschiedenen Entwickler-Releases.

Man findet auch immer Quell-Code-Releases von Ruby; man findet auch vorkompilierte Binär-Dateien für Windows oder andere Betriebssysteme (wie etwa die binäre Distribution von Ruby für windows bei http://www.pragmaticprogrammer.com/ruby/downloads/ruby-install.html).

Sidebar: Das ganz neuste Ruby

Für diejenigen, die immer das Allerneuste, Frisch-aus-der-Presse und Ungetestete haben müssen (wie wir, als wir dieses Buch schrieben) gibt es Entwickler-Versionen direkt aus der Entwickler-Werkstatt.

Die Ruby-Entwickler benutzen CVS (Concurrent Version System, frei erhältlich bei http://www.cvshome.com) als ihr Versions-Kontroll-System. Man kann als anonymer User Dateien aus ihrem Archiv auschecken (also lesen) mit den folgenden CVS-Kommandos:

% cvs -d :pserver:[email protected]:/home/cvs
   login
(Logging in to [email protected])
CVS password: guest
% cvs -d :pserver:[email protected]:/home/cvs
   checkout ruby

Der komplette Quell-Code-Baum, just wie die Entwickler ihn gerade auch sehen, wird nun in ein ``Ruby''-Unterverzeichnis auf dem lokalen Computer kopiert, wobei der dort vorhandene Quellcode-Baum aktualisiert wird von einer Quelle auf der anderen Seite der Welt. Sind das nicht großartige Zeiten, in denen wir leben?

Building Ruby

In der Ruby-Distribution findet man eine Datei namens README, die die Installations-Prozedur detailiert beschreibt. Kurz gesagt erzeugt man Ruby auf einem POSIX-basierten System mit den selben vier Kommandos wie bei den meisten anderen Open-Source-Anwendungen auch: ./configure, make, make test und make install. Man kann Ruby auch unter anderen Umgebungen (inklusive Windows) erzeugen, mit einer POSIX-Emulation wie cygwin[Siehe http://sourceware.cygnus.com/cygwin für Einzelheiten.] oder mit einem systemeigenen Compiler --- beschreiben ab ``ntsetup.bat'' im win32-Unterverzeichnis.

Ruby laufen lassen

Nachdem Ruby installiert ist, möchte man wahrscheinlich ein paar Programme laufen lassen. Anders als in kompilierten Umgebungen kann man Ruby auf zwei verschiedene Arten laufen lassen --- interaktiv oder als Programm.

Interaktives Ruby

Die leichteste Art, Ruby interaktiv laufen zu lassen ist, einfach nur ``ruby'' am Eingabe-Prompt einzutippen.

% ruby
puts "Hello, world!"
^D
Hello, world!

Wir haben hier den einfachen puts-Ausdruck und ein End-of-File-Zeichen eingegeben (bei unserem System ist das Control-D). Das funktioniert, aber es ist unangenehm, wenn man einen Tippfehler macht, außerdem kann man nicht wirklich sehen, was vor sich geht während man tippt.

Im Beispiel-Ordner der Ruby-Distribution findet man ein Script namens ``eval.rb''. Das ist eine Stufe besser, denn es zeigt uns den Wert jedes Ausdrucks so wie er eingegeben wird:

% cd sample
% ruby eval.rb
ruby> a = "Hello, world!"
"Hello, world!"
ruby> puts a
Hello, world!
nil
ruby> ^D
%

Hier können wir den Output von puts sehen und danach den Rückgabewert von puts (der nil ist).

Das ist alles schön und gut, außer dass Ausdrücke, die über mehrere Zeilen gehen, nicht funktionieren, und man kann die aktuelle Zeile nicht bearbeiten oder gar zurückgehen und vorhergehende Zeilen benutzen (wie man das mit dem Kommando history in einer Shell machen kann).

Als nächste Stufe bei eval.rb haben wir irb---Interaktives Ruby. irb ist eine Ruby-Shell, komplett mit einer Kommandozeilen-History, der Möglichkeit, Zeilen zu bearbeiten und job control (der Übersetzer: ach ja?). Das Ganze ist recht gut konfigurierbar und hat einen Haufen Optionen, so viele, dass es einen eigenen Anhang ab Seite 523 besitzt. Wir empfehlen dir, dich mit irb vertraut zu machen, damit du einige unserer Beispiele interaktiv ausprobieren kannst.

Ruby-Programme

Schließlich kann man auch ein Ruby-Programm von einer Datei aus laufen lassen genauso wie ein Shell-Script, Perl- oder Python-Programm. Man lässt einfach Ruby laufen und gibt den Script-Namen als Argument mit:

% ruby myprog.rb

Dann kann man noch die ``Shebang''-Notation von Unix als erste Zeile der Programm-Datei benutzen.[Wenn dein System das unterstützt, kannst du direkte Hineinschreiben des Pfades für Ruby in die Shebang-Zeile umgehen, indem du #!/usr/bin/env ruby benutzt, damit wird der Pfad für ruby gesucht und dann ausgeführt.]

#!/usr/local/bin/ruby -w

puts "Hello, World!"

Wenn man diese Quelldatei ausführbar macht (etwa mit chmod +x myprog.rb), dann kann man sie unter Unix als Programm laufen lassen:

% ./myprog.rb
Hello, World!

Man kann etwas Ähnliches auch unter Windows mit Datei-Zuordnungen machen.

Resourcen

Besuche die Ruby-Web-Seiten http://www.rubycentral.com und http://www.ruby-lang.org, da gibts alle Neuigkeiten, da kann man mit anderen Ruby-Anwendern chatten oder Mailing-Listen beitreten (siehe Anhang C).

Ganz bestimmt würden wir uns freuen, von dir zu hören. Kommentare, Vorschläge, Fehler im Text und Probleme in den Beispielen sind alle willkommen. E-mail uns:

mailto:[email protected]

Wenn du uns über Fehler im Buch berichtest, fügen wir sie der Errata-Liste hinzu:

http://www.pragmaticprogrammer.com/ruby/errata/errata.html

Schließlich enthält http://www.pragmaticprogrammer.com/ruby noch den Quell-Code für fast alle Beispiele aus dem Buch, sortiert nach der Seite.

Danksagungen

So ein Buch ist ein erhebliches Unterfangen, eines das wir niemals ohne die Hilfe all unserer Freunde, alte und neue, vollendet hätten. Wir sind stolz zu unseren alten Freunden zählen zu dürfen: das Team bei Addison-Wesley: Mike Hendrickson, John Fuller, die immer-hilfreiche Julie Steele und die wundervolle Julie DiNicola. Danke euch allen.

Unsere Korrektoren waren fantastisch. Wir ließen sie auf einige unbeschreiblich knappen Deadlines auflaufen und sie überstanden das für uns. Es ist nicht einfach, ein Buch voller technischer Details Korrektur zu lesen, daher sind wir besonders dankbar George Coe, Bob Davison, Jeff Deifik, Hal Fulton, Tadayoshi Funaba, Clemens Hintze, Kazuhiro Hiwada, Kikutani Makoto, Mike Linksvayer, Aleksi Niemelä, Lew Perin, Jared Richardson, Armin Roehrl, Conrad Schneiker, Patrick Schoenbach, and Eric Vought. Unser Dank gilt auch den beiden Julies bei Addison-Wesley für die Koordination dieses wirklich internationalen Unternehmens.

Einige Leute halfen uns bei speziellen Gebieten aus diesem Buch. Mit Tadayoshi Funaba tauschten wir unzählige E-Mails aus bis wir endlich das Date-Module verstanden hatten. Guy Decoux und Clemens Hintze beantworteten uns geduldig alle Fragen, wie man Ruby-Erweiterungen schreibt und Masaki Suketa half uns das WinOLE-Modul zu verstehen.

Obwohl die meisten Ruby-Dokumentationen in Japanisch sind, gibt es eine wachsende Anzahl von englischen Übersetzungen (der Übersetzer: vielleicht ja auch bald deutschen), das meiste von japanischen Entwicklern geschrieben, deren Umgang mir dem Englischen uns ein unablässiger Quell der Freude war. Obwohl es dabei zu viele individuelle Beiträge gab um sie alle zu nennen, möchten wir einen einzelnen herausstellen, Goto Kentaro, der einen großen Band mit hoch-qualitativer Dokumentation produziert und ins Netz gestellt hat.

Schließlich müssen wir Yukihiro ``Matz'' Matsumoto danken, dem Erfinder von Ruby. Wir haben die Fragen nicht mehr zählen können, die wir ihm gestellt haben, und auch nicht all seine detaillierten und geduldigen Antworten. Matz hat nicht nur eine wirklich tolle Sprache erfunden, er hat auch eine wunderbar unterstützende und offene Kultur vorangetrieben, in der diese Sprache sich entwickeln kann.

Danke euch allen. Domo arigato gozaimasu.

Dave Thomas und Andy Hunt
THE PRAGMATIC PROGRAMMERS
http://www.pragmaticprogrammer.com

Notationen

In diesem Buch benutzen wir die folgenden typographischen Notationen.

Literale Code-Beispiel stehen in einem Typewriter-ähnlichen Font:

class SampleCode
  def run
    #...
  end
end

Innerhalb des Textes ist Fred#doIt eine Referenz auf die Instanz-Methode (doIt) der Klasse Fred, während Fred.new[In manchen anderen Ruby-Dokumentationen findet man Klassen-Methoden in Form von Fred::new. Das ist absolut gültige Ruby-Syntax; wir glauben einfach nur, dass Fred.new beim Lesen weniger störend ist.] eine Klassen-Methode ist und Fred::EOF eine Klassen-Konstante ist.

Das Buch enthält viele Schnipsel Ruby-Code. Wo es möglich war, haben wir versucht zu zeigen was passiert, wenn sie laufen. In einfachen Fällen zeigen wir den Wert von Ausdrücken auf der selben Zeile wie die Ausdrücke. Zum Beispiel:

a = 1
b = 2
a + b » 3

Manchmal waren uns auch die Werte von Zuweisungen wichtig, dann zeigen wir diese auch.

a = 1 » 1
b = 2 » 2
a + b » 3

Falls das Programm einen etwas komplexeren Output erzeugt, zeigen wir ihn unterhalb des Programm-Codes:

3.times { puts "Hello!" }
erzeugt:
Hello!
Hello!
Hello!

In einigen Bibliotheks-Dokumentationen wollten wir zeigen, an welchen Stellen im Output Leerzeichen stehen. Man sieht diese Leerzeichen als ``[visible space]''-Zeichen.

Kommando-Zeilen-Aufrufe erscheinen als Text im Roman-Font und Parameter, die man dazugibt, in Kursiv-Schrift. Optionele Elemente stehen in großen eckigen Klammern.

ruby [flags]*[progname][arguments]+


Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Übersetzung: Jürgen Katins
Für das englische Original:
© 2000 Addison Wesley Longman, Inc. Released under the terms of the Open Publication License V1.0. That reference is available for download.
Diese Lizenz sowie das Original vom Herbst 2001 bilden die Grundlage der Übersetzung
Es wird darauf hingewiesen, dass sich die Lizenz des englischen Originals inzwischen geändert hat.
Für die deutsche Übersetzung:
© 2002 Jürgen Katins
Der Copyright-Eigner stellt folgende Lizenzen zur Verfügung:
Nicht-freie Lizenz:
This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/). Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.
Freie Lizenz:
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".