Ruby Workshop für Anfänger

Winfried Mueller, www.reintechnisch.de, Start: 28.04.2005, Stand: 29.04.2005

(Begleitendes Workshop Skript, erster Workshop war am 29.04.2005 bei der Dortmunder Linux Gruppe)

Lektion I - Überblick

  • Ruby ist eine Skriptsprache, wie Perl, Python, PHP, Shell-Skript
  • Quellcode wird intepretiert, nicht zuvor kompiliert
  • Ursprung: Japan, erste Release 1995 von Yukihiro "Matz" Matsumoto (* 1965)
  • Matz leitet auch heute noch das Ruby-Projekt
  • in Japan so verbreitet, wie hier Perl und Python
  • Sprachorientierung:
    • konsequent objektorientiert -> alles ist ein Objekt
    • Ideen aus Perl, Python, Smalltalk u.a.
    • "principle of least surprise" - alles soll sich möglichst so verhalten, wie man es erwartet.
  • wg. Sprachbarriere der Dokumentation (japanisch) erst stärkere Verbreitung um Jahr 2000 (erstes Ruby Buch in Englisch erscheint). Seither starkes Wachstum in der Anwendung weltweit.
  • Ruby im weltweiten Kontext eine junge Sprache. Hat noch lange nicht die Bedeutung, wie Perl oder Python. Wird wahrscheinlich in 5 Jahren ähnlichen Stellenwert haben.
  • Ruby ist wie Perl und Python seit Version 1.6 (2002) stabil und für den Produktiveinsatz bestens geeignet.
  • plattformunabhängig: verfügbar für Linux, Windows, BSD, Mac OS X, *nix und weitere
  • Einsatzgebiete: Wie Perl, Python und PHP auch:
    • Werkzeuge Systemadministration
    • webbasierte Anwendungen, Webentwicklung
    • Prototypen
    • Wegwerfskripte
    • Kommandozeilen-orientiert und GUI-orientiert
    • Netzwerk-Tools
    • Datenbankunterstützung für alle gängigen SQL-Datenbanken vorhanden

Lektion II - Ausgabe

 
# -- Programm 1: Hello World
puts "Hello World!"
# --

# -- Programm 2: Ausgabe Experimente I
print "Hello World!\n" * 3
# --

# -- Programm 3: Ausgabe Experimente II
a = "World"
puts "Hello #{a}!"
puts "Hello " + a + "!"
puts "Hello " + a.upcase + "!"
# --

# -- Programm 4: Ausgabe Experimente III
a = "Hello"
b = "World"
c = 10
printf( "%s %s!\n", a, b )
printf "%s %s!\n", a.upcase, b.upcase
printf "%d x %s %s!\n", c, a.downcase, b.downcase
printf "Laenge a: %d Laenge b: %d\n", a.length, b.length 
#--


# -- Programm 5: Ausgabe Experimente IV
printf "Laenge const: %d\n", "Ruby".length
printf "Ruby verschluesselt: %s\n", "Ruby".crypt( "salt" )
printf "Gefunden bei Stelle: %d\n", "Das ist Ruby".index( "Ruby" )
#--

# -- Programm 6: Ausgabe Experimente V
s = "Das ist Ruby"
printf "Ein Teilstring: %s\n", s[8..11]
printf "Ein Teilstring: %s\n", s[8..-1]
# --


Lektion III - Eingabe/Ausgabe

 
# -- Programm 7: Logdatei lesen und auswerten I
s = File.readlines( "syslog" )
puts s
# --

# -- Programm 8: Logdatei lesen und auswerten I
s = File.readlines( "syslog" )

s.each do |line|
  puts line
end
# --

# -- Programm 9: Logdatei lesen und auswerten II
s = File.readlines( "syslog" )

s.each do |line|
  if line =~ /cron/i
    puts line
  end
end
# --

# -- Programm 10: Logdatei lesen und auswerten III
s = File.readlines( "syslog" )

s.each do |line|
  if line =~ /^(\w+) (\d+) (\d+):(\d+):(\d+) (\w+) (.*?): (.*)$/
    tm  = Time.local( "2005", $1, $2, $3, $4, $5 )
    host = $6
    prg = $7
    msg = $8
    puts "----"
    puts tm
    puts "  Host: " + host
    puts "  Programm: " + prg
    puts "  Message : " + msg
  else
    raise "Falsche Syslog Zeile"
  end
end
# --

# -- Programm 11: Logdatei lesen und auswerten IV
def writer1( tm, host, prg, msg )
  puts "----"
  puts tm
  puts "  Host:     " + host
  puts "  Programm: " + prg
  puts "  Message : " + msg

end

def writer2( a, b, c, d )
  printf "%s %s %s\n", a, c, d 
end

def msg_select?( tm, host, prg, msg)
  if prg =~ /cron/i
    return true
  else
    return false
  end
end

s = File.readlines( "syslog" )

s.each do |line|
  if line =~ /^(\w+) (\d+) (\d+):(\d+):(\d+) (\w+) (.*?): (.*)$/
    tm  = Time.local( "2005", $1, $2, $3, $4, $5 )
    host = $6
    prg = $7
    msg = $8
    if msg_select?( tm, host, prg, msg )
      writer1( tm, host, prg, msg )
    end
  else
    raise "Falsche Syslog Zeile"
  end
end

# --

# -- Programm 12: Logdatei lesen und auswerten V
class SyslogMsg
  include Comparable
  def initialize( tm, host, prg, msg )
    @tm   = tm
    @host = host
    @prg  = prg
    @msg  = msg
  end
  attr_reader :tm, :host, :prg, :msg

  def <=>( other )
    @tm <=> other.tm
  end

  def to_s
    "----\n"  +
    tm.to_s + "\n" +
    "  Host:     " + host + "\n" +
    "  Programm: " + prg + "\n" +
    "  Message : " + msg + "\n"
  end

end

s = File.readlines( "syslog" )

messages = Array.new
s.each do |line|
  if line =~ /^(\w+) (\d+) (\d+):(\d+):(\d+) (\w+) (.*?): (.*)$/
    tm  = Time.local( "2005", $1, $2, $3, $4, $5 )
    host = $6
    prg = $7
    msg = $8
    messages << SyslogMsg.new( tm, host, prg, msg )
  else
    raise "Falsche Syslog Zeile"
  end
end

messages.each do |msg|
  puts msg if msg.prg[ /cron/i ]
  #puts msg if msg > messages[messages.length - 10]
  #puts msg if msg < messages[10]
end

# --


Lektion IV - Bisher eingesetzte Sprachmöglichkeiten

 
Ausgabe:

  puts string
  puts "Hello World"
  puts "Hello" + " " + "World"

  print "Hello World\n"

  printf "%s %s\n", "Hello", "World"


Einlesen einer Text-Datei:

  arr = File.readlines( filename )

Strings:
  s = "Hello"
  s.upcase
  s.downcase
  s.length
  s[1..3]
  s[2..-1]
  s.crypt( salt )
  s.index( string )


Reguläre Ausdrücke:
  if s =~ /ausdruck/
  if s =~ /ausdruck/i

  Teilausdrücke: $1..$n


Ranges:
  1..n
  1..-1

Arrays:
  arr = [1, 2, 3]

  arr = Array.new

  arr.each do |element|
    ...
  end

  puts arr[index]
  arr[index] = object

  arr << object



Methoden/Funktionsdefinition:

def my_methode( par1 )
  return par1 + 1
end


Klassen:
  class MyClass
    def initialize( par1, par2 )
      @obj_var1 = par1
      @obj_var2 = par2
    end
    attr_reader :obj_var1, :obj_var2

    def my_methode( par1 )
      r = "Return Value"
      return r
    end

    def +( other )
      @obj_var1 + other.obj_var1
    end
  end

  my_obj = MyClass.new( 10, 20 )


Kontrollstrukturen:
  if ausdruck
    ...
  else
    ...
  end

  puts "Hello" if ausdruck


Symbole:
  :name


Fehlerbehandlung:
  raise "Fehler"

Variablen:
  lokale Variablen:
    a = 10
    s = "Hello"

  globale Variablen:
    $a = 10
    $str = "Hello"

  Konstanten:
    A   = 10
    STR = "Hello"


Syntax-Infos:
  - Bezeichner, die mit Großbuchstaben beginnen:
    - Klassennamen
    - Konstanten

  - Bezeichner, die mit Kleinbuchstaben beginnen:
    - lokale Variablen
    - Methoden
    - Objekt-Variablen

  - Einrückungen nur für Lesbarkeit

  - Kein Semikolon am Ende einer Anweisung (Perl, C, PHP)

  - Blöcke entweder begin...end oder {...}


Lektion V - Ausblick

Grundlegende Klassen:

  • String
  • Array
  • Hash
  • Fixnum
  • Float
  • File, IO
  • Dir
  • Proc
  • Range
  • Regexp
  • Time
  • Module Comparable
  • Module Enumerable
  • Module Kernel
  • NilClass
  • TrueClass, FalseClass

Kontrollstrukturen:

  • case
  • if
  • loop
  • while, until
  • for
  • next, break, redo
  • Fehlerbehandlung: rescue, ensure, raise

Gute Unterstützung in Ruby:

  • Textmanipulation (regexp, Parser, Lexer, Formatierung, Konverter)
  • Netzwerk
    • Mail: smtp, pop3, IMAP, Mailmanipulation, Mailgenerierung
    • Internet: http, ftp, ssl, eigenständiger Webserver (webrick), XML
    • Shell: telnet, ssh
    • Webentwicklung: mehrere Web-Frameworks (Ruby On Rails, Wee, Amrita, Nitro), Bildbearbeitung mit ImageMagick
    • Client/Server Programming: Distributed Ruby (dRuby)
    • Socket-Programmierung: tcpsocket, udpsocket ...
  • Administration
    • syslog
    • tar, zlib
    • Encryption
    • Multithreading
    • Server/Daemons
    • XML
    • Bildbearbeitung mit ImageMagick
  • GUI
    • Fox GUI
    • Ruby TK
  • Windows
    • Zugriff auf Windows API, DLL-Zugriff, OLE-Zugriff
    • Registry-Manipulation
  • Datenbank
    • Zugriff auf alle gängigen SQL-Datenbanken
    • einheitliches Interface, Kapselung der darunterliegenden Datenbank
    • objektorientierte Datenbankadapter (z.B. Nitro/ Og)
  • Persistenz/Serialisierungssprachen
    • PStore - Objekte auf Festplatte ablegen
    • YAML - Serialisierungssprache, auch ideal für Configdateien
  • IRB: interaktiv Ruby Shell
  • Dokumentation:

Weblinks