Ruby on Rails: Einfachheit ist das Prinzip

15.09.2006
Von Norbert Ehreke 
Wenn es um die Auswahl von Entwicklungswerkzeugen für Web-Anwendungen geht, ist das Framework "Rails" inzwischen zu einem ernst zu nehmenden Kandidaten herangewachsen.
Das Rails-Framework basiert auf der seit 1995 existierenden Programmiersprache "Ruby", die als Nachfolgerin von Perl verstanden wird.
Das Rails-Framework basiert auf der seit 1995 existierenden Programmiersprache "Ruby", die als Nachfolgerin von Perl verstanden wird.

Das Rails-Framework ist in der Firma 37Signals von David Heinemeier Hasson entstanden. Das Unternehmen hat eine Reihe von Web-Anwendungen entwickelt und befand, dass einige Bestandteile daraus im Rahmen eines Frameworks ausgelagert und als gemeinsame Codebasis für den Entwurf neuer Anwendungen genutzt werden können. Das Rails-Framework basiert auf der Computersprache Ruby, die als Nachfolger von Perl verstanden wird. Sie existiert bereits seit 1995, doch erst durch den Erfolg des Rails-Frameworks hat Ruby derart an Popularität gewonnen, dass Unternehmen in größerem Stil auf diese Technik aufmerksam geworden sind. Ihr Fokus liegt auf leicht verständlichem sowie gut wart- und testbarem Code. Selbst in C programmiert, lässt sich Ruby durch relativ einfache Mechanismen erweitern. Sowohl Ruby als auch Ruby on Rails (RoR) sind Open Source und damit ohne Lizenzkosten zu verwenden. Unter den Plattformen werden die gängigen Betriebssysteme Unix, Linux, Mac OS X und natürlich Windows unterstützt.

Keine Unterstützung

Ruby on Rails wird im Gegensatz zu anderen Open-Source-Projekten wie Linux oder Eclipse derzeit nicht durch große Hersteller gefördert. Unter Umständen wird die Plattform für Anwenderunternehmen aber erst dann interessant, wenn sich diese Situation ändert. Durch die Aufteilung der Enterprise-Welt in Java und .NET scheint es jedoch unwahrscheinlich, dass ein Global Player strategisch auf Ruby on Rails setzen wird, so attraktiv die Technik auch sein mag.

Das Konzept

Die RoR-Erfinder wenden sich mit ihrem Framework in erster Linie an Entwickler, die zur Lösung eines Business-Problems gewissermaßen auf der "grünen Wiese" aufsetzen können. Ihnen gibt Rails technische Hilfsmittel an die Hand, mit denen sie den Geschäftsvorfall möglichst schnell und effizient objektorientiert abbilden und daraus ein Datenbankschema ableiten können.

Die Erweiterung eines klassischen relationalen Legacy-Systems um eine Rails-Anwendung zählt dagegen nicht zu den favorisierten Einsatzgebieten. In diesen Fällen ist bereits ein relationales Datenmodell vorgegeben, aus dem ein objektorientiertes Anwendungsmodell abgeleitet werden müsste, und dieser Weg entspricht nicht der Ruby-Philosophie.

Fazit

• Der große Erfolg von Ruby on Rails liegt in der Produktivitätssteigerung der Ent-wickler.

• Die Codierung setzt sich mit Business-Problemen auseinander und nicht mit Sekundärproblemen wie Verteilung, Datenbank- interaktion und Java-Scripting.

• Es handelt sich um eine stabile, effiziente Web-Entwicklungsplattform, die einen Vergleich mit den etablierten Enterprise- Systemen nicht zu scheuen braucht.

Mehr zum Thema

www.computerwoche.de/

579949: Kritische Schwachstelle in Ruby on Rails;

1215634: Vista vereint Web- und Rich-Client;

580806: Visual Composer von SAP.

Weitere Links

• http://www.rubyonrails.org; • http://new.ruby-lang.org/;

• http://www.rubyonrails.org/ applications;

• http://martinfowler.com/ bliki/EnterpriseRails.html;

• Kommodo, Ruby IDE: http://www.activestate.com/;

• RadRails, Rails IDE: http://www.radrails.org;

• Sprachenvergleich: http://www.approximity.com/ ruby/Comparison_rb_st_m _java.html;

• YAML: http://de.wikipedia. org/wiki/YAML.

Zwischen Java und PHP

Doch zunächst zur Programmiersprache Ruby. Im Vergleich der für die Web-Entwicklung verfügbaren Tools nimmt Ruby gewissermaßen eine Zwischenstellung ein. Die Sprache ist objektorientiert wie Java und C#, die im Umfeld geschäftlicher Web-Anwendungen wohl die größte Verbreitung haben. Auf der anderen Seite handelt es sich bei Ruby um eine interpretierte Sprache, was einen Vergleich mit PHP und Perl nahe legt, die in der Web-Entwicklung ebenfalls häufig anzutreffen sind, jedoch eher im Bereich kleiner bis mittlerer Anwendungen genutzt werden. Da PHP und Perl aber nicht wirklich objektorientiert sind, wird hier auf einen Vergleich mit diesen Skriptsprachen verzichtet.

Der wohl auffälligste Unterschied zwischen Java beziehungsweise C# und Ruby liegt in der Einsatzkonzeption. Technisch gesehen können Java und C# als systemorientierte Sprachen betrachtet werden, was im Gegensatz zu Sprachen wie PHP, Perl oder Ruby steht, die eine stärkere Abstraktion von systemimmanenten Aspekten (beispielsweise Typisierung oder Deklarationen) voraussetzen und damit dem Entwickler die Konzentration auf die eigentliche Business-Problematik erleichtern sollen.

Ein weiterer grundlegender Unterschied besteht darin, dass Ruby im Gegensatz zu Java und C# eine interpretierte Sprache ist. Damit entfällt die gesamte Kompilierung. Auf diese Weise wird der Entwicklungsprozess deutlich beschleunigt, da zum Beispiel Änderungen an einem Programm ohne die Zwischenstufen der Kompilierung und aufwändigen Verteilung auf den Web-Server sofort sichtbar werden.

Objektorientierung

In Ruby ist alles ein Objekt - ein Ansatz, der aus der Programmiersprache Smalltalk bekannt ist. Das führt unter anderem dazu, dass es im Gegensatz zu C# oder Java keine primitiven Datentypen wie "int" oder "float" gibt. Neben den bekannten objektorientierten Möglichkeiten bietet Ruby eine Reihe von weiterführenden Techniken. Ein Beispiel dafür sind "Blocks", auch "Closures" genannt, mit denen das aus Smalltalk bekannte Paradigma der funktionalen Programmierung wieder ins Gespräch gebracht wird. Ein Block ist ein Satz von Ruby-Ausdrücken und Anweisungen, die als letztes Argument einer Methode verwendet werden können. In Sprachen wie Java, C# oder C++, die ohne Closures arbeiten, ist dieses Programmierkonzept nur sehr aufwändig umzusetzen.

Selbstverständlich stehen in Ruby auch Techniken etwa zur Ausnahmebehandlung (Exception Handling), Zugriffskon- trolle für "Member" und "Methoden" (public, protected, private) sowie Funktionsmodule zur Verfügung. Ruby erlaubt zwar keine Mehrfachvererbung, bietet allerdings die Verwen- dung so genannter Mix-ins an. Dabei handelt es sich um Mo- dule, in denen der Entwickler eine Reihe von Methoden zusammenfassen kann, um diese jederzeit in andere Klassen einzubinden. Auf diese Weise lässt sich der Code sehr elegant modularisieren.

Ferner ist Ruby eine dynamische Sprache, die es erlaubt, den Sprachumfang zur Laufzeit zu erweitern. So lassen sich Ruby-Objekte dynamisch typisieren, was bedeutet, dass sich im Gegensatz zu C# und Java die Typ-Zuweisung einer Variablen abhängig von ihrem Wert während der Laufzeit ändern kann. Genau diese Eigenschaft wird jedoch von vielen Entwicklern, insbesondere den Verfechtern einer starken Typisierung, als schwerwiegender Nachteil aufgefasst. Ihnen kommt das jüngst unter dem Begriff "Generics" für C# und Java vorgestellte Konzept entgegen, wonach schon während des Kompiliervorgangs unveränderbar festgelegt wird, welche Typen ein Objekt, insbesondere Listen von Objekten, enthalten darf.

Dennoch ist bislang nicht bekannt, dass Ruby-Systeme aufgrund der dynamischen Typisierung in der Praxis Probleme bereitet hätten. Immerhin erspart dieses Vorgehen eine aufwändige Codierung, die insbesondere dann anfallen würde, wenn es um systemübergreifende Aufgaben geht: So etwa die Interaktion mit einer relationalen Datenbank oder die dynamische Funktionserweiterung via Plug-in, wie sie zum Beispiel aus der Eclipse-Entwicklungsumgebung bekannt ist.

Was Rails draufsetzt

Die Sprache Ruby ist schnell zu erlernen. Erfahrungsgemäß verläuft die Entwicklung von RoR-Projekten tatsächlich ein- facher und schneller im Vergleich zu den etablierten Konkurrenten Java und C#. Die klassische Rails-Anwendung basiert auf einer Datenbank (unterstützt werden unter anderem DB2, MySQL, Oracle, PostgreSQL, SQL Server und SQLite), wobei der Rails-Entwickler die Modellierung grundsätzlich objektorientiert vornimmt. Das so entstehende relationale Modell der Datenbank folgt also dem OO-Design des Programmierers. Dieser Umstand ist je nach Struktur der Entwicklermannschaft sowohl Chance als auch Risiko, denn die Abbildung einer objektorientierten An- wendung in einer relationalen Datenbank ist keinesfalls trivial und kann bei schlechter Umsetzung zu Performance-Problemen führen.

Anwendungen erzeugen

Die Vorgehensweise zur Erstellung von Ruby-on-Rails-An- wendungen erfolgt nach einem bewährten Schema. Unter Zuhilfenahme eines Web-Servers (Apache, IIS oder der im SDK-Umfang enthaltene WeBrick) wird im Web-Verzeichnis eine Reihe von Ordnern per Skript angelegt. Je nach Aufgabe werden in den Ordnern die benötigten Ruby-Codedateien entwickelt. Die Datenbankkonfiguration erfolgt über einen YAML-File (YAML Ant Markup Language: eine im Vergleich zu XML leichtgewichtige formale Sprache zur einfachen Erstellung von leicht lesbaren Konfigurationsdateien).

Rails arbeitet mit einer Reihe von Annahmen, die dem Prinzip folgen, dass Konventionen gegenüber Konfigurationen vor-zuziehen sind ("Convention over Configuration"). Während die Web-Entwicklung beispielsweise in Java mit Deployment-Deskriptoren, XML-Mapping-Dateien und einer Vielzahl von Frameworks arbeitet, versucht Rails, intelligente Annahmen zur Abbildung von Abhängigkeiten zwischen Komponenten herzustellen, die meist vollkommen ausreichen und den Entwick-lungsprozess beschleunigen, da sie aufwändiges Coding ersparen. Eine Konvention ist zum Beispiel die simple Zuordnung, dass sich eine Datenbanktabelle mit Namen "orders" in einer Ruby-Klasse mit der Bezeichnung "Order" abbildet. Zur Anbindung von Legacy-Systemen müssen solche Default-Einstellungen natürlich programmatisch angepasst und geändert werden.

Datenbank bildet Klassen ab

Für die Oberflächenentwicklung verwendet Rails das Konzept des Model View Controller (MVC), das sich mittlerweile als Standard etabliert hat. Auf diese Weise können Entwickler Aktionen wie Klicks und Submits in einfacher Manier auf immer ähnliche Art und Weise behandeln. So bilden sich Datenbanktabellen durch simple Regeln direkt in entsprechende Klassen in Rails ab, die über den als "Active Record" bezeichneten Object Relational Mapper (ORM) von Rails ohne großen Aufwand gelesen und geschrieben werden können.

Durch das so genannte Scaffolding (Gerüstbau) wird die Entwicklung einer Web-Anwendung, die sich mit der Darstellung und Bearbeitung von Datensätzen im weitesten Sinn beschäftigt, stark vereinfacht. Scaffolding bedeutet, dass Rails während der Entwicklung Codeteile generiert, die sich je nach Anforderung des Projekts vom Programmierer erweitern beziehungsweise vervollständigen lassen. Die URLs einer Rails-Anwendung sind transparent und einfach aufgebaut. Grob gesprochen sehen sie immer so aus: "http://<application>/<controller>/<action>". XML als konfigurations- und kontextbeschreibende Umgebung fällt komplett weg.

Vergleichbar mit den Tools Ant oder Make bietet die Ruby-Plattform ein Skripting-Tool namens "Rake", mit dem automatisierbare, voneinander abhängige Aufgaben gelöst werden können. Mit Rake lassen sich zum Beispiel Änderungen in einer Web-Anwendung verwalten, so dass sich diese versioniert durch das gesamte Rails-Projekt ziehen, also von der Datenbank bis zum Frontend. Entsprechend ein- fach kann man solche, auch als Migrationen bezeichnete Entwicklungen vollständig zurücknehmen. Als Beitrag zur Verbesserung der Softwarequalität unterstützt Rails zudem auto- matisierte Tests und betrachtet diese als Teil des Entwicklungsprozesses.

Kritiker werfen Rails vor, dass es bislang kein Referenzprojekt gibt, das mit der Leistung von J2EE- oder ASP.NET-Lösungen im klassischen Portalbereich etwa für Online-Banking oder Enterprise-Shopping-Systeme mithalten kann. Die potenzielle Skalierbarkeit von RoR-Anwendungen hat sich damit zu einem zentralen Diskussionsthema zwischen den Lagern entwickelt.

Skalierbarkeit beweisbar?

Die Vertreter der Ruby-on-Rails-Plattform führen jedoch Referenzbeispiele an, mit denen man beweisen will, dass die auf diesem Weg entstandenen Anwendungen ebenso skalieren wie J2EE- oder ASP.NET-Anwendungen. Zum anderen stellt sich die Frage, ob die klassischen Bottlenecks der mit RoR umgesetzten Enterprise-Systeme in Wirklichkeit nicht in der Mittelschicht, sondern eher im Backend, also in der Datenbank liegen, weil etwa die Abbildung der Objektstrukturen im relationalen Modell unglücklich gewählt wurde.

Ein weiterer Kritikpunkt an Rails ist die stringent praktizierte Philosophie der Einfachheit. Lebende Enterprise-Systeme hingegen sind alles andere als einfach, und diese in Rails abzubilden ist unter Umständen unmöglich.

Restriktionen

Beispielsweise unterstützt Rails derzeit in den Datenbankta- bellen keine Verbundschlüssel (Compound Keys) und erlaubt lediglich Integer-Werte als Primärschlüssel (Primary Key). Für Datenmodelle, in denen Unique Identifier (UID) als Primärschlüssel verwendet werden (oder eben Compound Keys), ist Rails nur unter Schwierigkeiten anwendbar. Derzeit wird in der Rails-Community darüber diskutiert, wie man mit derartigen Restriktionen umzugehen hat.

Schließlich löst RoR die grundlegenden Probleme von Web-Entwicklung genauso wenig wie ASP.NET oder J2EE. Das Hypertext Transfer Protocol (http) ist und bleibt ein zustandsloses Protokoll, und eine Simulation von Client-seitiger Intelligenz durch Javascript, neuerdings ver-packt in Ajax, bleibt ebenfalls eine Krücke. Dieses grundlegende Problem betrifft prinzipiell jede Web-Entwicklungsplattform, also auch Rails. (ue)