Die Programmiersprache Ruby

Blog| Forum| Wiki  

PHP ist eine auf dynamische Webseiten spezialisierte Scriptsprache. Es gibt zwar schon seit längerem einen Interpreter für Konsolenanwendungen und es ist auch möglich, grafische Anwendungen mit GTK+ 1 zu erstellen, in der Praxis findet dies aber praktisch keine Anwendung. Es sind kaum Bibliotheken verfügbar, die für Webapplikationen keinen Sinn machen (wie z. B. GUI). Ruby hingegen ist eine echte All-Purpose Sprache. Hiermit können sowohl Konsolenanwendungen geschrieben werden, es ist eine Vielzahl an GUI-Toolkits und Bibliotheken verfügbar, Spiele sind genauso möglich wie Datenbank- oder Netzwerkzugriffe. Webapplikationen sind natürlich auch möglich (siehe Rails).

Inhaltsverzeichnis

Verbreitung

Der Vorteil von PHP ist seine Verbreitung. Praktisch auf jedem Webserver kann man PHP-Skripte ausführen, während man Webapplikations-Unterstützung für Ruby schon suchen muss. Wegen der großen Konkurrenz auf dem Servermarkt lohnt es sich aber durchaus, einfach beim Hoster des Vertrauens nachzufragen, gerade kleinere Firmen installieren den Support schon nach. Auch bei der Dokumentation ist PHP durch seine Verbreitung im Vorteil, da vielfältige deutschsprachige Dokumentationen vorliegen. Hiermit kann Ruby noch nicht aufwarten, es ist zwar bereits einiges Englisch verfügbar, aber gerade in Deutsch fehlt noch vieles. Es gibt einige Tutorials in Deutsch. In Foren zu Ruby wird praktisch jede Frage innerhalb von Stunden kompetent beantwortet.

Konsistenz

PHP, ursprünglich als Perlscript-Sammlung geschrieben, wurde inzwischen mehrfach in C neu implementiert. Trotzdem gibt es viele Inkonsistenzen, PHP erscheint oft mit dem Fokus auf Funktionalität entwickelt worden zu sein, ein durchgehendes Konzept wurde dabei offensichtlich vernachlässigt. Bei Ruby hingegen wurde viel Zeit mit der Konzeption zugebracht, weshalb die Sprache einen sehr konsistenten Eindruck macht. Deshalb funktioniert hier aus dem Kopf geschriebener Code oft direkt, während man bei PHP gern mal die Reihenfolge der Parameter durcheinander bringt (strpos($string, $gesuchtesWort), aber in_array($gesuchtesElement, $array)), vergisst, ob eine Funktion den Parameter bearbeitet, zurückgibt oder den Parameter selbst verändert (sort() ändert das übergebene Array, array_reverse() gibt ein überarbeites Array zurück) oder die Inkonsistenz der Funktionsnamen verwirrt (ini_get(), aber getenv()). In Ruby tragen Methodennamen, die ein Objekt verändern, ein Ausrufezeichen im Namen (es sei denn, dies geht bereits aus dem Namen hervor) und können so einfach von denen unterschieden werden, die direkt das Objekt zurückgeben (reverse und reverse!).

Syntax

PHP ist eine prozedurale Sprache. Sie verfügt zwar über grundlegende Konzepte der Objektorientierung, kommt dabei aber bei weitem nicht an die von Ruby heran. Vor allem ist aber fast die gesamte Standardbibliothek prozedual ausgelegt. In Ruby kann man auch gut prozedual programmieren, an objektorientierte Konzepte kann man sich so langsam heranwagen. Dies fällt auch recht leicht, da die Objektorientierung von Ruby nicht so sperrig ist wie die beispielsweise von Java (an der sich die Objektorientierung von PHP orientiert).

Die Syntax von Ruby ist einfacher, offener und flexibler als die von PHP:

  • So muss man kein Semikolon am Ende jeder Zeile einfügen, aber man kann.
  • Man braucht für Methodenaufrufe keine Klammern um die Argumente setzen, aber man kann.
  • Man kann statt geschweifter Klammern auch Schlüsselwörter wie do und end verwenden. Durch die objektorientiere Schreibweise wirken viele Sachen lesbarer.
  • Ruby verwendet für die Definition einer Funktion / Methode eine an BASIC angelehnte Schreibweise. Der Anweisungen-Teil der Methode wird in Ruby wie folgt gekennzeichnet:
1
2
def foobar
end

Im Vergleich dazu eine Funktionsdefinition in PHP:

1
2
function foobar() {
}
  • Ruby Anweisungen können über mehrere Zeilen gehen, wenn das Zeilenende mit \ escaped wird (es zählt als Leerzeichen):
1
2
puts "erste Zeile", \
"zweite Zeile"

Die Schreibweise in Ruby orientiert sich also stark an Sprachen wie BASIC. PHP dagegen ist stärker an Sprachen wie C++ und Java angelehnt, deren Laufzeit-Umgebungen verbreiteter sind.

Typisierung

Als Typ einer Variable bezeichnet man die Art von Daten, die sie enthält, also beispielsweise Zeichen, eine Ganzzahl oder mehrere andere Variablen (Array). Sowohl PHP als auch Ruby sind dynamisch typisierte Sprachen, was bedeutet, dass eine Variable keinen festen Typ hat, sondern je nach Bedarf Daten unterschiedlichen Typs speichern kann. PHP geht jedoch noch weiter und sorgt dafür, dass sich der Inhalt einer Variable der Situation anpasst, während Ruby dies lieber der Kontrolle des Programmierers überlasst. Vergleicht man beispielsweise einen Text, der eine Zahl enthält, mit einer Zahl, dann wird der Text automatisch in die Zahl konvertiert. Bei Ruby muss der Programmierer das explizit veranlassen.

PHP:

1
2
3
4
"2005" == 2005 // Ergibt true
"2005" === 2005 // Ergibt false
"23" * 5 // Ergibt 115
"ho! " * 3 // Ergibt 0, da keine Zahl als 0 definiert ist

Ruby:

1
2
3
4
"2005" == 2005 # Ergibt false
"2005".to_i == 2005 # Ergibt true
"23" * 5 # Ergibt "2323232323"
"ho! " * 3 # Ergibt "ho! ho! ho! "

Mancher mag das Verhalten von PHP als positiv empfinden, zumal man bei Bedarf auch einen typstrengen Vergleich machen kann (was aber nicht so bekannt ist). Viele empfinden es jedoch als zu beliebig, da es teilweise nicht intuitiv ist. So werden die Werte 0, "" und "0" bei einem True/False-Vergleich als False angesehen, was für den Programmierer nicht immer vorhersehbar ist (z. B. wenn der Wert aus einer Benutzereingabe stammt). Und leider schlägt auch hier wieder die PHP-typische Inkonsistenz zu:

1
2
3
4
5
# Die folgende Vergleiche ergeben alle true:
"0.0" == 0.0 
0.0 == false
"0.0" == true // obwohl 0.0 == false
"false" != false

Anmerkung: In PHP gibt es den "typensicheren" Vergleichsoperator === der sich verhält wie Rubys "==". PHP bietet der Programmiererin also mehr Möglichkeiten als Ruby.

Auch benötigt PHP deshalb einen besonderen Operator zum Verketten von Strings, den Punkt.

1
2
"Hallo " + "Welt!" // Ergibt 0, da Strings in diesem Fall als 0 interpretiert werden.
"Hallo " . "Welt!" // Ergibt "Hallo Welt!"

Sicherheit

PHP wird oft als Einsteigersprache bezeichnet. Dabei wird aber meist nur bedacht, dass es im Vergleich zu manch älterer Sprache wie Perl oder C etwas einfacher zu erlernen ist, ein wichtiges Kriterium wird oft vergessen: In einer Einsteigersprache sollte es nicht zu einfach sein, sich Sicherheitslücken in eine Anwendung zu reißen. In diesem Punkt leistet sich PHP leider große Patzer. Das seit PHP 4.2 in der Standardkonfiguration deaktivierte, weil potentiell unsicherere Verhalten, dass per GET, POST oder Cookie übergebene Werte als Variablen registriert wurden, ist noch immer bei vielen Hostern aktiviert, um alte und auf alt geschriebene Skripte lauffähig zu halten. Auch ist es bei PHP direkt möglich, Variablenwerte, die vom Nutzer eingegeben wurden, direkt mittels eval auszuführen, und es können beliebige Variablen in PHP zur Einbindung von Dateien von anderen Internetservern benutzt werden. Wer hier nicht genau weiß, was er tut, kann hier unwissentlich große Scheunentore öffnen.

Ruby bietet hier ein besseres Sicherheitskonzept. Zum einen gibt es die spezielle Variable [[$SAFE]]. In ihrem Standardwert 0 ist alles erlaubt, aber je weiter man sie erhöht, umso mehr unsichere Aktionen werden verboten. Die Variable kann zwar erhöht werden, aber nicht mehr verkleinert. Es ist also nicht möglich, durch eine eventuell gefundene Sicherheitslücke die Sicherheitsstufe wieder zu reduzieren. Zusätzlich speichert Ruby für jede Variable, ob sie aus einer sicheren Quelle kommt (also direkt im aktuellen Skript definiert ist) oder ob sie aus einer nicht vertrauenswürdigen Quelle stammt (Usereingaben, aus einer Datei oder Datenbank eingelesen etc.). Ab $SAFE >= 1 ist es nicht mehr möglich, möglicherweise gefährliche Funktionen mit Werten aus unsicheren Variablen durchzuführen. Man kann diese Variablen nicht ohne weiteres zur Ausführung an eval übergeben; Dateien mit dem Namen des Inhalts einer unsicheren Variable können weder gelesen noch geschrieben werden; und so weiter. Bis $SAFE < 3 ist es noch möglich, unsichere Variablen als sicher zu markieren (was man nur nach guter Prüfung machen sollte), es ist also weiterhin möglich, solchen Code bei Bedarf auszuführen, aber es kann dem Programmierer nicht aus Versehen passieren.

Natürlich kann dieses Verhalten nicht gegen alle Sicherheitslücken schützen, aber eine Vielzahl von typischen Lücken in PHP wird hierdurch gut verhindert. Wer die Gefahren kennt, kann theoretisch auch sichere Skripte in PHP schreiben, nur ist niemand immer wachsam. Mir selbst (iGEL) ist durch eine Sicherheitslücke im phpBB ein Schaden von 70 € entstanden, da ein Wurm auf das System eindringen konnte und in einer einzigen Nacht ca. 65 GB Traffic erzeugt hatte (Für die Lücke stand zugegebenermaßen bereits seit zwei Monaten ein Fix bereit). Mit dem Konzept von Ruby wäre das wohl nicht passiert.

Quellcodevergleiche

Verbesserungen sowohl bei PHP als auch bei Ruby willkommen!

PHP:

1
2
3
4
$array = array("Fr��hling", "Sommer", "Herbst", "Winter");
sort($array);
$array = array_reverse($array);
print $array[2];

Ruby:

print ["Fr��hling", "Sommer", "Herbst", "Winter"].sort.reverse[2]

Anmerkung von Meillo 2006-12-18: Ein bisschen unfairer Vergleich, denn sort() ist halt nunmal schlecht designed. Verschachtelung von Funktionen ist natürlich möglich. PHP-Beispiel:

$array = array_reverse(array_unique(array("a", "b", "b", "c", "a")));

Nichts desto trotz ist Ruby da halt einfach eleganter ;-)


PHP:

1
2
3
foreach range (1, 10) as $i {
  echo $i;
}


Ruby:

1
2
3
(1..10).each do |i|
  print i
end