Die Programmiersprache Ruby

Blog| Forum| Wiki  


Ruby
Datei:Ruby_Logo.png
Das offizielle Logo von Ruby.
Entwickler: Yukihiro "Matz" Matsumoto
Aktuelle stabile Version: 2.3.3 und 2.4.0 (Stand 10.01.2017)
Betriebssystem: Diverse.
Lizenz: 2-Klausel-BSDL + Eigene
Website: http://www.ruby-lang.org

Inhaltsverzeichnis

Entstehung

Ruby ist eine komplett objektorientierte, höhere Programmiersprache und wurde (und wird) von Yukihiro "Matz" Matsumoto entwickelt. Ruby entstand 1993 (zu dem Zeitpunkt noch ohne Code!) aus Unzufriedenheit Matz' über andere Programmiersprachen. Python war ihm nicht objektorientiert genug, C zu statisch, Perl nicht mächtig genug. Also vereinte er die seiner Meinung nach besten Eigenschaften aller ihm bekannten Programmiersprachen (sein Liebling war zu diesem Zeitpunkt angeblich Smalltalk) und schuf die nach dem kostbaren Edelstein und als Anspielung auf Perl benannte Sprache Ruby. Aus diesem Grund liegt Ruby eine wohl einzigartige Interpretation des "Prinzips der geringsten Überrschung" zugrunde, Matz selbst sagt dazu:

"Das Prinzip der geringsten Überrschung ist das Prinzip meiner geringsten Überraschung. Und das Prinzip der geringsten Überraschung, nachdem du Ruby gut gelernt hast."

Für weitere Prinzipien, siehe Rubys Prinzipien.

Die offizielle Website von Ruby ist ruby-lang.org. Wer sich für das allerneueste interessiert und des Japanischen mächtig ist, kann sich Matz' Blog ansehen. Eine Liste der Webseiten rund um Ruby gibt es hier.

Die Sprache selbst

Hinweis: Hierbei handelt es sich um eine Übersetzung der Rubrik Features aus Rubys Manpage.

...ist interpretiert

Ruby ist eine interpretierte Sprache, d.h. du musst deine Programe nicht ständig neu kompilieren, um sie auszuführen.

$ ruby dein_skript.rb


...besitzt Variablen ohne Typen (dynamische Typisierung)

Variablen können in Ruby Daten jeglichen Typs enthalten, du musst dir demnach keine Sorgen über Variablentypen machen. Die Konsequenz daraus ist aber, dass Ruby schwächere Compile-Time-Prüfungen hat.

1
2
3
i = 3
x = "abcde"
q = [1, "b", 6.4, [1, :a]]


...benötigt keine Deklarationen

Du kannst Variablen ohne Deklaration verwenden. Die Namen jeder Variable enhalten bereits die Information, ob sie lokal, global, instanzbezogen, etc. ist.

1
2
3
a = 3
q = "abc"
@ivar = [1, 2, 3]


...hat eine einfache Syntax

Rubys menschenlesbare Syntax wurde leicht von Eiffel beeinflusst.

1
2
a = rand(10)
puts a if a < 5


...braucht keine manuelle Speicherverwaltung

Ruby besitzt ein automatisches Speichermanagement. Objekte, die keine Referenzen mehr besitzen, werden automatisch vom eingebauten Garbage Collector eingesammelt.

1
2
3
4
ary = [1, 2, 3, 4]
ary2 = ary
ary = ary2 = nil
#Den Rest erledigt der GC.


...ist vollständig objektorientiert

Ruby ist eine vollständig objektorientierte Sprache und war es seit ihrer Erschaffung. Selbst grundlegende Dinge wie Zahlen werden als Objekte behandelt.

1
2
3
3.times do
  puts "Hello!"
end


...kennt Klassen, Vererbung und Methoden

Selbstverständlich hat Ruby als objektorientierte Sprache solch grundlegende Features wie Klassen, Vererbung und Methoden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Car
  
  def initialize
    @velocity = 0
  end
  
  def speed_up(n)
    @velocity += n
  end
  
end

class Lamborghini < Car
  
  def speed_up(n)
    super(n * 4)
    puts "ROAR!!"
  end
  
end

my_car = Lamborghini.new
my_car.speed_up


...kann mit Singletonmethoden umgehen

In Ruby gibt es die Möglichkeit, Methoden für einzelne Objekte zu definieren. Zum Beispiel kannst du eine Button-Klick-Aktion für ein spezielles Widget mithilfe einer Singleton-Methode definieren, oder du könntest dein eigenes, prototypen-basiertes Objektsystem über Singleton-Methoden realisieren (wenn du das tatsächlich wolltest).

1
2
3
4
5
6
7
8
9
obj = Object.new
obj2 = Object.new

def obj.hello
  puts "hello"
end

obj.hello #=> hello
puts obj2.hello #| Error


...hat Mix-Ins

Ruby besitzt absichtlicherweise keine Mehrfachvererbung, was nicht selten Anlass zu Verwirrung gibt. Stattdessen kannst du in Ruby aber Implementations quer über den Vererbungsbaum verteilen; dies nennt man oftmals "Mix-In".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module MyMixin
  
  def cool
    puts "brr..."
  end
  
end

module My2ndMixin
  
  def hot
    puts "AHH!"
  end
  
end

class MyClass
  include MyMixin
  include My2ndMixin
end

x = MyClass.new
x.cool #=> brr...
x.hot #=> AHH!


...hat Iteratoren

Ruby besitzt Iteratoren, die Schleifen abstrahieren.

1
2
3
4
5
6
2.upto(4) do |i|
  puts i
end
#=> 2
#=> 3
#=> 4


...hat Closures

In Ruby kannst du Prozeduren objektorientiert machen.

1
2
3
4
5
6
7
8
9
def foo
  x = 3
  lambda{puts "x is: #{x}"}
end

#x is out of scope here!

l = foo
l.call #=> x is: 3


...hat keine Probleme mit Textverarbeitung und Regulären Ausdrücken

Ruby hat eine Menge Features zur Textverarbeitung wie etwa Perl.

1
2
3
4
5
6
7
8
str = "I *love* Ruby!"

str.split #=> ["I", "*love*", "Ruby!"]

match_data = str.match(/\*(.*?)\*/)
puts match_data[0] #=> *love*
puts match_data[1] #=> love
puts match_data.pre_match #=> I


...kann M17N und ist zeichensatzunabhängig

Ruby unterstützt multilinguale Programmierung. Es ist leicht, verschiedensprachige und in unterschiedlichen Zeichenkodierungen abgefasste Texte zu bearbeiten, ohne dabei jedoch von Unicode abhängig zu sein.

1
2
3
4
5
6
7
8
9
10
11
str = "Mit Umlaut: ��"
puts str.encoding #=> UTF-8
str.encode!("ISO-8859-1")
puts str.encoding #=> ISO-8859-1
str.force_encoding("UTF-8")
puts str.encoding #=> UTF-8
puts str.valid_encoding? #=> false
str.encode!("ISO-8859-1", :invalid => :replace, :replace => "?")
puts str.encoding #=> ISO-8859-1
puts str.valid_encoding? #=> true
puts str #=> Mit Umlaut: ?


...hat Bignums

Mit den eingebauten Bignums kannst du z.B. factorial(400) berechnen.

puts 40 ** 35 #=> 118059162071741130342400000000000000000000000000000000000


...ermöglicht Reflexion und Domain Specific Languages

Class ist auch eine Instanz der Klasse Class. Die Definition von Klassen und Methoden ist nur ein Ausdruck wie es auch 1 + 1 ist, sodass deine Programme sogar weitere Programme schreiben und sich selbst ändern können. Das bedeutet, dass du deine Anwendung in deiner eigenen, auf Ruby basierenden Programmiersprache schreiben kannst.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
puts Class.class #=> Class
puts Object.class #=> Class
puts Object.new.class #=> Object

x = Class.new do
  
  def hello
    puts "hello"
  end
  
end

y = x.new
puts y.hello #=> hello
puts y.class #=> #<Class:0x000000028009d8>

x.instance_eval do
  define_method(:a) do
    puts "a"
  end
end

y.a #=> a


...kennt objektorientierte Ausnahmenbehandlung

Wie in Java(tm).

1
2
3
4
5
6
begin
  raise(ArgumentError, "Something was wrong!")
rescue => e
  puts e.class #=> ArgumentError
  puts e.message #=> Something was wrong!
end


...hat direkten Zugriff auf das Betriebssystem

Ruby kann die meisten Unix-Systembefehle direkt benutzen, was oft in systemnaher Programmierung benötigt wird.

syscall(4, 1, "hello\n", 6) #=> hello


...kann dynamisch laden

Auf den meisten Unix-Systemen (und auch auf Windows) kannst du Object-Dateien (DLLs auf Windows) on-the-fly in den Ruby-Interpreter laden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require "psych" #Psych is a YAML parser written in C

puts Psych.load(Psych.dump([1, 2])) #=> [1, 2]

#For libs not written for Ruby
require "ffi"

module LibC
  extend FFI::Library
  
  ffi_lib FFI::Library::LIBC
  
  attach_function(:puts, [:string], :void)
end

LibC.puts("hello") #=> hello


...besitzt viele Bibliotheken

Programmbibliotheken namens "builtin libraries" und "standard libraries" werden mit Ruby verteilt. Und es ist kinderleicht, weitere Bibliotheken mithilfe des Paketsystems RubyGems zu installieren.

Außerdem gibt es Tausende Ruby-Projekte auf Rubyforge und im RAA.

# gem install ffi mechanize coderay gosu rails mail nokogiri RedCloth ...


Rubys Syntax

Rubys Syntax ist sehr leserlich (außer man legt es drauf an, siehe HowToObfuscate). Matz hat einmal gesagt, "Ich will Ruby natürlich machen, nicht einfach". Ein vollständiges Ruby-Programm sieht bereits so aus:

puts "Hello world!"

Es wird keine Klasse benötigt, in der der Code ausgeführt wird, denn Rubyprogramme werden grundsätzlich immer von einem "Main"-Objekt eingefasst. Klammern um Methodenargumente sind in den meisten Fällen optional, das bedeutet ebenfalls eine Erleichterung des Lesens von Rubys ohnehin schon "federleichter" Syntax.

Die bereits oben beschriebene Flexibilität von Ruby bringt natürlich auch Nachteile mit sich. So ist Ruby nicht typensicher, man kann einer Methode grundsätzlich alle Typen von Argumenten übergeben und die Methode muss sehen, wie sie damit klar kommt. Auch kann es vorkommen, dass Methoden z.B. der Klasse String während der Laufzeit überschrieben oder entfernt werden, was dazu führen kann, dass unter Umständen das gesamte Programm nicht mehr funktionsfähig ist.

1
2
3
4
#Das sollte man NICHT tun
class Object
  undef initialize
end


Ruby 1.9 und 2

Ruby ist im Umbruch. Momentan wird die Sprache von dem Entwicklerteam um Matz komplett überarbeitet; die daraus entstehende Version Ruby 2 wird nicht abwärtskompatibel sein. Dies tritt bereits bei Ruby 1.9.1 heraus und wird sich wohl zu Ruby 2 hin noch verstärken, das RubyWiki-Team arbeitet an einer Liste der Veränderungen von Ruby 1.8 zu 1.9. Wie groß die Unterschiede der zwei Versionen sind, zeigt zum Beispiel, dass das Rubyforum verschiedene Rubriken für Ruby 1.8 und 1.9 besitzt.

Siehe auch