„Ruby (Programmiersprache)“ – Versionsunterschied
[gesichtete Version] | [gesichtete Version] |
K →Prototypenbasierte Objektorientierung: Wikipedia:Liste von Tippfehlern/ O |
Rechtschreibung |
||
Zeile 19: | Zeile 19: | ||
'''Ruby''' (engl. für [[Rubin]]) ist eine moderne, vielseitige [[höhere Programmiersprache]], die Mitte der Neunziger Jahre vom Japaner [[Yukihiro Matsumoto]] entworfen wurde. |
'''Ruby''' (engl. für [[Rubin]]) ist eine moderne, vielseitige [[höhere Programmiersprache]], die Mitte der Neunziger Jahre vom Japaner [[Yukihiro Matsumoto]] entworfen wurde. |
||
Sie |
Sie [[Interpreter|interpretiert]] und unterstützt mehrere [[Programmierparadigma|Programmierparadigmen]] (unter anderem [[Objektorientierte Programmierung|Objektorientierte]], [[Prozedurale Programmierung|Prozedurale]] und [[Funktionale Programmierung]] sowie [[Nebenläufigkeit]]), bietet [[dynamische Typisierung]], [[Reflexion (Programmierung)|Reflexion]] und [[Garbage Collection|Automatische Speicherbereinigung]]. |
||
== Geschichte == |
== Geschichte == |
Version vom 10. März 2009, 21:30 Uhr
Ruby | |
---|---|
![]() | |
Basisdaten | |
Paradigmen: | multiparadigmatisch |
Erscheinungsjahr: | 1995 |
Designer: | Yukihiro Matsumoto |
Entwickler: | Yukihiro Matsumoto und andere |
Aktuelle Version: | 1.9.1 (31. Januar 2009[1]) |
Typisierung: | dynamisch („Duck-Typing“) |
Wichtige Implementierungen: | Ruby MRI, YARV, JRuby, Rubinius (siehe unten) |
Beeinflusst von: | Smalltalk, Perl, Python, LISP, Scheme, CLU, Eiffel, Ada, Dylan, Javascript |
Beeinflusste: | Groovy |
Betriebssystem: | plattformunabhängig |
Lizenz: | GPL und eigene (siehe Nutzungsbedingungen) |
ruby-lang.org |
Ruby (engl. für Rubin) ist eine moderne, vielseitige höhere Programmiersprache, die Mitte der Neunziger Jahre vom Japaner Yukihiro Matsumoto entworfen wurde.
Sie interpretiert und unterstützt mehrere Programmierparadigmen (unter anderem Objektorientierte, Prozedurale und Funktionale Programmierung sowie Nebenläufigkeit), bietet dynamische Typisierung, Reflexion und Automatische Speicherbereinigung.
Geschichte
Aus Unzufriedenheit über verfügbare Skriptsprachen begann Yukihiro „Matz“ Matsumoto 1993 an einer eigenen Sprache zu arbeiten und gab am 21. Dezember 1995 die erste Version von Ruby, 0.95, frei.[2] Den Namen, hergeleitet vom Edelstein Rubin, wählte er als Anspielung auf die Programmiersprache Perl.[3] Zunächst wurde Ruby mangels englischsprachiger Dokumentation fast ausschließlich in Japan benutzt, wo es einen ähnlichen Stellenwert erlangte wie Perl und Python in Europa und Amerika. Um das Jahr 2000 wurden Aktivitäten gestartet, um Ruby auch außerhalb Japans bekannt zu machen, woraufhin mit der Zeit auch englische Dokumentationen entstanden. Inzwischen gibt es auch dutzende deutschsprachige Bücher zu Ruby im Allgemeinen und speziellen Themen.
Heute wird die Sprache als Open-Source-Projekt weitergepflegt.
Merkmale
Programmierparadigmen
Ruby ist eine objektorientierte Sprache. Die Sprache wurde aber ähnlich wie C++ als „Multiparadigmen-Sprache“ entworfen. Das bedeutet, dass es dem Entwickler offensteht, weitere Programmierparadigmen zur Erstellung seiner Programme zu nutzen. Drei verbreitete Paradigmen sollen im Folgenden beschrieben werden.
Objektorientierte Programmierung
Ruby ist wie Smalltalk vollständig objektorientiert: Alle Funktionen in Ruby sind Methoden und alle Datentypen sind Objekte, auch solche, die in vielen anderen Sprachen als primitive Datentypen gelten.
Ruby unterstützt mehrere Ansätze der Objektorientierung.
Klassenbasierte Objektorientierung
Folgende Sprachkonstrukte mit Zahlen und Zeichenketten sind möglich:
puts 42.class # Ausgabe: Fixnum
puts "ein kurzer String".class # Ausgabe: String
Eine Klasse, die automatisch von der Mutterklasse Object
erbt, könnte wie folgt definiert werden:
class Auto
def beschleunigen
puts "BrumBrumBrum"
end
end
auto1 = Auto.new
auto1.beschleunigen
Ausgabe:
BrumBrumBrum
Eine Klasse, die von einer anderen Klasse als Object
erbt, wird so definiert:
class GutesAuto < Auto
def bremsen
puts "Quietsch"
end
end
auto2 = GutesAuto.new
auto2.beschleunigen
auto2.bremsen
Ausgabe:
BrumBrumBrum Quietsch
Die Klasse GutesAuto
erbt alle Methoden der Klasse Auto
, u. a. auch beschleunigen
. Zusätzlich wird für GutesAuto
die Methode bremsen
definiert.
Prototypenbasierte Objektorientierung
Ruby unterstützt zudem, ähnlich wie JavaScript oder Io, prototypenbasierte Objektorientierung.
Das obige Beispiel mit Prototypen realisiert:
auto1 = Object.new
def auto1.beschleunigen
puts "BrumBrumBrum"
end
auto1.beschleunigen
auto2 = auto1.clone
def auto2.bremsen
puts "Quietsch"
end
auto2.beschleunigen
auto2.bremsen
Ausgabe:
BrumBrumBrum BrumBrumBrum Quietsch
Objektorientierung mit Mixins
Bis vor einiger Zeit wurden Mixins als reine Ergänzung zu klassenbasierter Objektorientierung angesehe. Spätestens aber seit Sprachen wie Potion ist klar, dass es sich hierbei um ein eigenes Konzept der Objektorientierung handelt. Dieses wird auch von Ruby unterstützt.
In Ruby sind Mixins Module, die in andere Objekte eingebunden werden. Die Methoden des Beispiels aus den beiden oberen Abschnitten ließe sich zum Beispiel so in Module teilen:
module Gaspedal
def beschleunigen
puts "BrumBrumBrum"
end
end
module Bremse
def bremsen
puts "Quietsch"
end
end
Ein Auto mit Gaspedal und Bremsen ließe sich dann wie folgt zusammenbauen:
auto = Object.new
auto.extend Gaspedal
auto.extend Bremse
Natürlich lässt sich das mit Klassen kombinieren:
class Auto
include Gaspedal
end
class GutesAuto < Auto
include Bremsen
end
Aber auch mit Prototypen ist es nutzbar:
auto1 = Object.new
auto1.extend Gaspedal
auto2 = auto1.clone
auto2.extend Bremsen
Prozedurale Programmierung
Im Gegensatz zu Sprachen wie Java und C# ist es in Ruby nicht notwendig, seine Programme explizit in einer Klasse zu definieren. Da jedes Ruby-Programm in einem globalen main
-Objekt erstellt wird, ist dieses sich oft wiederholende Sprachkonstrukt unnötig. Stattdessen kann ein Programm auch aus Prozeduren aufgebaut werden. Folgender Codeabschnitt ist bereits ein vollständig lauffähiges Ruby-Programm:
def gruessen
puts "Hallo Welt!"
end
gruessen
Funktionale Programmierung
Weil in Ruby jeder Ausdruck einen Wert hat, lassen sich Probleme funktional behandeln.
Im folgenden Beispiel gibt das case-Konstrukt je nach Wert der Bedingung einen anderen String zurück.
gruss = case sprache
when "Deutsch" then "Hallo Welt"
when "Englisch" then "Hello, world"
when "Japanisch" then "konnichiwa sekai"
else raise "Unbekannte Sprache"
end
Über ein Lambda-Konstrukt kann man einen Codeblock in einer Funktionsvariablen speichern.
print_function = lambda { |item| print item + 1 }
[1,2,3].each &print_function
# >> 234
Weitere Paradigmen
Ruby unsterstützt Metaprogrammierung, aspektorientierte Programmierung durch Active Support oder AspectR[4] und kontextorientierte Programmierung[5] durch ContextR[6].
Prinzipien
Prinzip der geringsten Überraschung
Ruby folgt dem Prinzip der geringsten Überraschung (kurz POLS für „Principle of least surprise“). Rubys Designer versuchen, die Sprache so zu gestalten, dass Programmierer sie intuitiv nutzen können und möglichst wenig von ihrem Verhalten überrascht werden. Matsumoto gibt an, die Sprache primär auf seine eigenen Bedürfnisse ausgerichtet zu haben:
„Das Prinzip der geringsten Überraschung ist das Prinzip meiner geringsten Überraschung. Und es ist das Prinzip der geringsten Überraschung nachdem Du Ruby sehr gut gelernt hast.“
Duck Typing
Die Duck-Typing-Philosophie von Ruby basiert auf der Idee, die Behandlung eines Objekts nicht von dessen Klasse, sondern von dessen Methoden abhängig zu machen.
class Ente
def beschreibung
"Eine dicke Ente"
end
def quak
"Quaaaaaak!"
end
end
class Frosch
def beschreibung
"Ein grüner Frosch"
end
def quak
"Quak! Quak!"
end
end
def lass_quaken tier
puts tier.beschreibung+" macht "+tier.quak
end
lass_quaken Ente.new
lass_quaken Frosch.new
Ausgabe:
Eine dicke Ente macht Quaaaaaak! Ein grüner Frosch macht Quak! Quak!
Im Beispiel ist es für lass_quaken
unerheblich, von welcher Klasse tier
ist, es ist nur wichtig, dass die Methoden beschreibung
und quak
verstanden werden.
Ruby bietet Exceptions, Introspection und andere Mechanismen, um das Duck Typing abzusichern, sofern der Programmierer das wünscht.
Syntax
Besonderheiten
Zeilenumbrüche markieren das Ende einer Anweisung, Semikolons bewirken dasselbe. Sonstiger Whitespace hat keine Bedeutung.
Klammern um Argumente können bei Eindeutigkeit weggelassen werden, sowohl bei der Deklaration einer Methode, als auch beim Aufruf. Der zuletzt berechnete Wert einer Methode ist gleichzeitig ihr Rückgabewert:
def sperre text
text.split("").join " "
end
puts sperre "Syntaktischer Zucker!"
Ruby unterscheidet fünf verschiedene Gültigkeitsbereiche:
- Normalerweise ist eine Variable lokal und nur innerhalb der umgebenden Methode gültig.
- Ein
@
vor Variablen deklariert diese als Attribute, sie werden dann dauerhaft der Klasseninstanz zugeordnet und für diese sichtbar. - Ein vorangestelltes
@@
macht Variablen zu Klassenvariablen, die zur umgebenden Klasse gehören. - Mit
$
werden Variablen global und sind damit im gesamten Programm sichtbar. - Schließlich gibt es Variablen, die nur innerhalb eines Blocks gültig sind.
Blöcke
Anstatt von For-Schleifen macht man in Ruby Gebrauch von sogenannten Blöcken. Dies sind Codeabschnitte, die nach bestimmten Vorgaben, etwa für alle Elemente einer Datenstruktur, ausgeführt werden. Sie können unter anderem benutzt werden, um Strukturen auszuwerten oder zu manipulieren. Ausdrücke wie
array.each do |i|
...
end
oder in der Kurzschreibweise
array.each{|i| ... }
iterieren über array
, wobei dem Block in jedem Iterationsschritt ein Visitor für das aktuelle Element mit der Bezeichnung i
übergeben wird.
Mit Blöcken werden elegante Konstruktionen wie 5.times{ ... }
oder array.sort_by{|i| i.size}
möglich.
Iteratoren, also Methoden, die Blöcke aufrufen, können auch selbst definiert werden:
def mach_zweimal
yield
yield
end
mach_zweimal{ puts "Block aufgerufen!" }
Ausgabe:
Block aufgerufen! Block aufgerufen!
Bestandteile
Interaktive Ruby-Shell
Interactive Ruby (kurz: irb) ist ein Read-Eval-Print Loop (kurz REPL) für Ruby, mit welchem der Anwender interaktiv Ruby programmieren kann. Er kann zum Analysieren und Testen eingesetzt werden:
irb(main):001:0> (5 + 7) * 2
=> 24
irb(main):002:0> ((5 + 7) * 2).to_s.reverse
=> "42"
irb(main):003:0> "Ein Beispielstring".size
=> 18
Irb wird mit dem Ruby-Interpreter ausgeliefert, kann aber auch mit Hilfe von TryRuby[7] im Browser ausgeführt werden.
RDoc und ri
RDoc ist ein Software-Dokumentationswerkzeug, welches aus Ruby- und C-Quelltexten automatisch HTML-Dokumentationsdateien erstellt. Weiterhin wird eine Datenbank aufgebaut, die mit dem Tool ri durchsucht werden kann. RDoc und ri sind Bestandteil der Standarddistribution und werden zusammen mit dem Interpreter ausgeliefert.
RubyGems
RubyGems (kurz: gems) ist das offizielle Paketsystem für Ruby. Mit ihm hat der Anwender die Möglichkeit mehrere Versionen eines Programmes oder einer Bibliothek kontrolliert zu installieren und wieder zu entfernen. Durch die Versionierung der Pakete können alte und neue Versionen problemlos nebeneinander existieren.
Implementierungen
Die ursprüngliche Referenzimplementierung von Ruby (aktuelle Version: 1.9.1) wurde von Yukihiro „Matz“ Matsumoto als Interpreter in C entworfen. Er wird oft als CRuby, MRI (Matz's Ruby Interpreter) oder MatzRuby bezeichnet und ist derzeit am weitesten verbreitet. Den Kern bildet YARV (kurz für Yet Another Ruby VM), eine virtuelle Maschine. Statt ein Rubyprogramm direkt auszuführen, wird es so zunächst in Bytecode übersetzt und dann von YARV interpretiert, wodurch sich ein Geschwindigkeitsvorteil ergibt. Weiterhin enthält diese Version eine leistungsstarke Regexp-Maschine namens Oniguruma und unterstützt Multibyte-Zeichensätze wie UTF-8. Die Vorgängerversion (1.8.7) wird vorerst weiter gepflegt, da 1.9.1 nicht kompatibel zu dieser ist und eine Vielzahl von Programmen deshalb noch nicht fehlerfrei auf der neuen Version laufen.
Der offizielle Interpreter läuft auf den folgenden Betriebssystemen:
Inzwischen sind mehrere alternative Implementierungen von Ruby verfügbar, unter anderem:
- JRuby[8], eine Neuimplementierung des Ruby-Interpreters in Java mit dem Ziel, Ruby nahtlos in die Java-Plattform zu integrieren. JRuby ist vollständig kompatibel zu Ruby 1.8, in der kommenden Version (1.2.0) auch zu 1.9. JRuby ist zudem kompatibel zu einigen Ruby-Erweiterungen von Rubinius (Foreign Function Interface, Multi-VM-API).
- Rubinius[9], eine von Smalltalk-80 inspirierte virtuelle Maschine. Abgesehen von der virtuellen Maschine ist Rubinius vollständig in Ruby implementiert. Rubinius wird als vollständig komaptibel zu Ruby 1.8 betrachtet. Die kommende Version von Rubinius (0.10) verfügt über verschiedene virtuelle Maschinen, die alle den gleichen Bytecode verstehen, um mit verschiedenen Optimierungsvarianten zu experimentieren.
- IronRuby[10] und Gardens Point Ruby.NET[11], die Ruby ins .NET-Framework integrieren sollen und in C# implementiert werden.
- Cardinal[12], ein Interpreter für die virtuelle Maschine Parrot
- XRuby[13], ein Compiler, der Ruby-Quelltext in Java-Bytecode übersetzt. Die Arbeit an XRuby wurde eingestellt.
- MagLev[14] ist eine proprietäre Implementierung des Unternehmens Gemstone für deren Smalltalk VM.
- MacRuby[15] ist eine Implementierung in Objective-C von Apple, die wie Ruby 1.9 YARV nutzt. MacRuby setzt als einzige Implementierung nur auf Kompatibilität zu Ruby 1.9, nicht aber zu Ruby 1.8.
- tinyrb[16] ist eine minimalistische Implementierung, angelehnt an die virtuellen Maschinen von Lua und Potion[17]. Es wird keine vollständige Kompatibiblität zu Ruby erreicht werden: Zwar soll jedes Programm, dass tinyrb ausführen kann, auch von Ruby ausführbar sein, jedoch soll tinyrb nicht jedes Rubyprogramm ausführen können.
- Ruby Enterprise Edition[18] ist eine modifizierte Version der Referenzimplementierung, bei der im wesentlichen der Garbage Collector neu implementiert wurde. (Siehe dazu: Kritik)
- Eine auf ABAP aufbauende Neuimplementierung wird im Moment am Hasso-Plattner-Institut entwickelt.
Kompatibilität zu Ruby 1.8 einer Implementation meint meist, dass diese zu 1.8.6 kompatibel ist. Es bezieht sich nicht auf die neuste Version der 1.8-Reihe (1.8.7), da in diese Sprachänderungen, wie etwa das Aufrufen von each ohne einen Block zu übergeben, aus 1.9 zurück fließen.
Ein wichtiges Merkmal ist hierbei, ob diese Implementierungen in der Lage sind, Ruby On Rails auszuführen. Derzeit können dies neben der Referenzimplementierung nur JRuby[19], Rubinius[20] und die Ruby Enterprise Edition[21] (Stand: Februar 2009).
Die Kompatibilität zur Referenzimplementierung wird durch das RubySpec Projekt[22] überprüft, dass im Moment von allen genannten Implementierungen, mit Ausnahme von tinyrb und Cardinal, genutzt wird (Stand: Februar 2009). Es stellt dabei sowohl eine Testsuite als auch eine Spezifikation für Ruby 1.8 und 1.9 dar. RubySpec war ursprünglich ein Teil von Rubinius, wurde aber ausgelagert und nun auch von einer Vielzahl anderer Entwickler vorangetrieben.
Kritik
Kritik an der Sprache:
- Da Variablen vor Gebrauch nicht deklariert werden müssen, können bei Tippfehlern unerwartete Laufzeitfehler auftreten.
- Ruby ist nicht immer abwärtskompatibel.[23]
- Metaprogrammierung und Monkeypatching erlauben es einem Codestück alle Klassen und Objekte des Prozesses, in dem es ausgeführt, zu ändern.[24]
- Ruby hatte bis vor kurzem keine offizielle Spezifikation. Allerdings wurde RubySpec von Matz als Spezifikation angenommen. Zudem gibt es von Matz und anderen Entwicklern das Bestreben eine weitere Spezifikation zu erstellen mit dem Ziel einen ISO-Standard zu etablieren.[25]
Kritik an der Referenzimplementierung:
- Der Garbage Collector manipuliert die Speichereinträge für Objekte direkt, sodass Copy-On-Write-Mechanismen des Betriebssystems ausgehebelt werden und es möglich ist, dass ein Rubyprogramm nach dem Durchlaufen des Garbage Collectors eventuell mehr Speicher belegt als zuvor.[26]
- Der Garbage Collector benutzt Mark-And-Sweep, was eine relativ simple, aber ineffiziente Strategie darstellt.[27]
- YARVs Global Interpreter Lock führt dazu, dass mehrere Threads eines Prozesses nicht gleichzeitig auf verschiedenen Prozessoren ausgeführt werden können.[28][29]
Zudem gibt es weitere Kritikpunkte an älteren Versionen der Referenzimplementierung, die mit Ruby 1.9 allerdings behoben wurden:
- Schlechte Performance, da der Rubycode direkt in einen Syntaxbaum, statt in Bytecode umgewandelt wird. [30]
- Unterstützt keine nativen Threads, was etwa das Potential von Mehrkernprozessoren nicht voll ausnutzt.[31]
- Bietet keine native Unterstützung für Unicode.[32]
Sonstiges
Anwendungen und Bibliotheken
Mit RubyForge und dem Ruby Application Archive (RAA) stehen zwei Repositorien zur Verfügung, die zusammen über 7000 Anwendungen und Bibliotheken beherbergen.[33][34]
Als derzeit bedeutendste Anwendung, die auf Ruby basiert, ist das Web-Framework Ruby on Rails zu nennen.
Nutzungsbedingungen
Ruby ist freie Software. Aufgrund dessen ist es kostenlos nutzbar und im Quelltext verfügbar. Dadurch ergibt sich die Möglichkeit, die Sprache an seine eigenen Bedürfnisse anzupassen oder sie in eigene Programme einzubinden.
Der Interpreter und die Standardbibliothek von Ruby sind grundsätzlich unter den Bedingungen der GPL nutzbar. Des Weiteren besteht die Möglichkeit, Ruby unter anderen Konditionen zu verwenden.[35]
Quellen
- ↑ Ruby 1.9.1 released
- ↑ RubyConf: History of Ruby
- ↑ Ein Interview mit dem Schöpfer von Ruby
- ↑ http://aspectr.sourceforge.net/
- ↑ http://www.swa.hpi.uni-potsdam.de/cop/
- ↑ http://contextr.rubyforge.org/
- ↑ TryRuby
- ↑ http://jruby.codehaus.org/
- ↑ http://rubini.us/
- ↑ http://www.ironruby.net/
- ↑ http://plas.fit.qut.edu.au/rubynet/
- ↑ http://cardinal2.rubyforge.org/
- ↑ http://xruby.com
- ↑ http://ruby.gemstone.com/
- ↑ http://www.macruby.org/trac/wiki/MacRuby
- ↑ http://macournoyer.com/blog/2009/02/12/tinyrb/
- ↑ http://github.com/why/potion
- ↑ http://www.rubyenterpriseedition.com
- ↑ http://wiki.jruby.org/wiki/JRuby_on_Rails
- ↑ http://blog.fallingsnow.net/2008/05/17/rails-on-rubinius/
- ↑ http://www.rubyenterpriseedition.com/
- ↑ http://rubyspec.org/
- ↑ http://www.infoq.com/news/2007/12/ruby-19
- ↑ http://avdi.org/devblog/2008/02/23/why-monkeypatching-is-destroying-ruby/
- ↑ http://www.ruby-forum.com/topic/169195
- ↑ http://blog.beaver.net/2005/03/ruby_gc_and_copyonwrite.html
- ↑ http://rubyconf2008.confreaks.com/how-ruby-can-be-fast.html
- ↑ http://www.infoq.com/news/2007/05/ruby-threading-futures
- ↑ http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
- ↑ http://www.joelonsoftware.com/items/2006/09/12.html
- ↑ http://spec.ruby-doc.org/wiki/Ruby_Threading
- ↑ http://headius.blogspot.com/2006/06/unicode-in-ruby-unicode-in-jruby.html
- ↑ RubyForge
- ↑ Ruby Application Archive
- ↑ Rubys Lizenzbedingungen
Literatur
- Für Einsteiger
- Daniel Bovensiepen: Das Einsteigerseminar Ruby. vmi Buch, Heidelberg 2007, ISBN 978-3826674594
- Sascha Kersken: Praxiswissen Ruby. O’Reilly, 2007, ISBN 978-3-89721-478-1
- Kevin C. Baird: Das Ruby-Praxisbuch. Franzis, 2008, ISBN 978-3-7723-7904-8
- Gesamtdarstellungen
- Dave Thomas: Programming Ruby, Second Edition. Pragmatic Bookshelf, 2004, ISBN 0-974-514-055 (englisch)
- Hal Fulton: The Ruby Way. Addison-Wesley Professional, 2006, ISBN 978-0672328848 (englisch)
- Für Fortgeschrittene
- Lucas Carlson, Leonard Richardson: Ruby Cookbook. O’Reilly Media, 2006, ISBN 978-0596523695 (englisch)
- Russ Olsen: Design Patterns in Ruby. Addison-Wesley Professional, 2007, ISBN 978-0321490452 (englisch)
- Referenzen
- Michael Fitzgerald: Ruby : kurz & gut. O’Reilly, 2007, ISBN 978-3897215344
Weblinks
- Offizielle Webseite von Ruby
- Zusammenstellung von Tutorials zu Ruby
- Dokumentationssammlung zu Ruby (englisch)
- Deutsches Rubyforum
- Linkkatalog zum Thema Ruby bei odp.org (ehemals DMOZ)