Update of exercises

master
Thomas Smits 2023-05-25 17:47:19 +02:00
parent 25d5ac7ffd
commit fe2c1c6eb6
73 changed files with 764 additions and 691 deletions

View File

@ -1,11 +1,22 @@
# Aufgabenblock 1: Ruby Grundlagen
# Splat
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Ruby Grundlagen__.
Sie haben ein Array mit folgendem Aufbau:
Folgende Themen werden durch die Aufgaben abgedeckt:
* Element 0: Breite
* Element 1: Länge
* Element 2: Name der Sehenswürdigkeit
* folgende Elemente: Weitere Informationen
* Kontrollstrukturen
* Schleifen
* Ausdrücke
Beispiel:
```ruby
ort = [ 49.468408, 8.482504, \
'Hochschule Mannheim', \
'Gebäude A', \
'Fakultät für Informatik', \
'Gute Ausbildung' ]
```
Lesen Sie die Elemente in _einem Schritt_ und in _einer einzigen Zuweisung_ in die Variablen `laenge`, `breite`, `name` und `attribute` ein. Verwenden Sie nicht die Indizes, sondern den Splat-Operator (`*`).

View File

@ -0,0 +1,12 @@
# Lösung: Splat
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
ort = [ 49.468408, 8.482504, \
'Hochschule Mannheim', \
'Gebäude A', \
'Fakultät für Informatik', \
'Gute Ausbildung' ]
laenge, breite, name, *attribute = ort
```

View File

@ -1,22 +1,13 @@
# Splat
# Symbole
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Sie haben ein Array mit folgendem Aufbau:
Verwenden Sie Symbole, um an eine Funktion `ansage` die Ursache für die Verspätung eines Zuges zu übergeben. Mögliche Ursachen sind
* Element 0: Breite
* Element 1: Länge
* Element 2: Name der Sehenswürdigkeit
* folgende Elemente: Weitere Informationen
* Signalstörung
* Personen im Gleis
* Störungen im Betriebsablauf
Beispiel:
Die Funktion soll dann den Text "Wir bitten um Entschuldigung, wegen ... verzögert sich unserer Weiterfahrt", wobei die Punkte durch die Ursache ersetzt werden sollen.
```ruby
ort = [ 49.468408, 8.482504, \
'Hochschule Mannheim', \
'Gebäude A', \
'Fakultät für Informatik', \
'Gute Ausbildung' ]
```
Lesen Sie die Elemente in _einem Schritt_ und in _einer einzigen Zuweisung_ in die Variablen `laenge`, `breite`, `name` und `attribute` ein. Verwenden Sie nicht die Indizes, sondern den Splat-Operator (`*`).
Rufen Sie die Funktion dann mit den verschiedenen Ursachen testweise auf.

View File

@ -1,12 +1,26 @@
# Lösung: Splat
# Lösung: Symbole
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
ort = [ 49.468408, 8.482504, \
'Hochschule Mannheim', \
'Gebäude A', \
'Fakultät für Informatik', \
'Gute Ausbildung' ]
def ansage(ursache)
laenge, breite, name, *attribute = ort
text = case ursache
when :signal
"Signalstörung"
when :personen
"Personen im Gleis"
when :betrieb
"Störungen im Betriebsablauf"
else
nil
end
puts "Wir bitten um Entschuldigung, wegen #{text} verzögert sich unsere Weiterfahrt" unless text.nil?
puts "Wir bitten um Entschuldigung. Unsere Weiterfahrt verzögert sich." if text.nil?
end
ansage(:signal)
ansage(:personen)
ansage(:betrieb)
ansage(:gibts_nicht) # keine Ausgabe
```

View File

@ -1,13 +1,20 @@
# Symbole
# Zugriffsmethoden
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Verwenden Sie Symbole, um an eine Funktion `ansage` die Ursache für die Verspätung eines Zuges zu übergeben. Mögliche Ursachen sind
Gegeben sei die folgende Ruby-Klasse:
* Signalstörung
* Personen im Gleis
* Störungen im Betriebsablauf
```ruby
class Professor
def initialize(name, fach)
@name = name
@fach = fach
end
Die Funktion soll dann den Text "Wir bitten um Entschuldigung, wegen ... verzögert sich unserer Weiterfahrt", wobei die Punkte durch die Ursache ersetzt werden sollen.
def to_s
"Prof. #{@name} lehrt #{@fach}"
end
end
```
Rufen Sie die Funktion dann mit den verschiedenen Ursachen testweise auf.
Ändern Sie die Klasse so ab, dass man die das Attribut `@name` lesen und das Attribut `@fach` lesen und schreiben kann. Verwenden Sie die `attr_`-Methoden, um eine möglichst kompakte Lösung zu bekommen.

View File

@ -1,26 +1,24 @@
# Lösung: Symbole
# Lösung: Zugriffsmethoden
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
def ansage(ursache)
class Professor
attr_reader :name
attr_accessor :fach
text = case ursache
when :signal
"Signalstörung"
when :personen
"Personen im Gleis"
when :betrieb
"Störungen im Betriebsablauf"
else
nil
def initialize(name, fach)
@name = name
@fach = fach
end
puts "Wir bitten um Entschuldigung, wegen #{text} verzögert sich unsere Weiterfahrt" unless text.nil?
puts "Wir bitten um Entschuldigung. Unsere Weiterfahrt verzögert sich." if text.nil?
def to_s
"Prof. #{@name} lehrt #{fach}"
end
end
ansage(:signal)
ansage(:personen)
ansage(:betrieb)
ansage(:gibts_nicht) # keine Ausgabe
p = Professor.new('Smits', 'PR3')
puts p.name
puts p.fach
p.fach = 'WIA'
puts p.fach
```

View File

@ -1,20 +1,13 @@
# Zugriffsmethoden
# Klasse deklarieren
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Gegeben sei die folgende Ruby-Klasse:
Schreiben Sie eine Ruby-Klasse `Ticket`, die Tickets für Fußballspiele repräsentieren kann. Die Klasse soll das Spiel und eine übergreifende Seriennummer speichern.
```ruby
class Professor
def initialize(name, fach)
@name = name
@fach = fach
end
Versehen Sie die Klasse mit einem Konstruktor, um Instanzen anlegen zu können. Der Konstruktor soll nur das Spiel bekommen, die Seriennummer verwaltet die Klasse selbst und zählt sie für jedes Ticket hoch.
def to_s
"Prof. #{@name} lehrt #{@fach}"
end
end
```
Überschreiben Sie die `to_s`-Methode so, dass man Tickets einfach ausgeben kann.
Ändern Sie die Klasse so ab, dass man die das Attribut `@name` lesen und das Attribut `@fach` lesen und schreiben kann. Verwenden Sie die `attr_`-Methoden, um eine möglichst kompakte Lösung zu bekommen.
Sehen Sie eine _statische_ Methode `verkauft` vor, um die aktuell verkaufte Anzahl von Tickets (höchste Seriennummer) auszulesen.
Testen Sie Ihre Klasse, indem Sie Objekte anlegen und ausgeben.

View File

@ -1,24 +1,31 @@
# Lösung: Zugriffsmethoden
# Lösung: Klasse deklarieren
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
class Professor
attr_reader :name
attr_accessor :fach
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Ticket
def initialize(name, fach)
@name = name
@fach = fach
attr_reader :spiel
@@seriennummer = 1
def initialize(spiel)
@spiel = spiel
@seriennummer = @@seriennummer
@@seriennummer += 1
end
def to_s
"Prof. #{@name} lehrt #{fach}"
"#{@spiel} [#{@seriennummer}]"
end
def self.verkauft
@@seriennummer
end
end
p = Professor.new('Smits', 'PR3')
puts p.name
puts p.fach
p.fach = 'WIA'
puts p.fach
t1 = Ticket.new('Dortmund-Schalke')
t2 = Ticket.new('Hoffenheim-Stuttgart')
puts t1
puts t2
puts Ticket::verkauft
```

View File

@ -1,13 +1,5 @@
# Klasse deklarieren
# Default Parameter
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Ruby-Klasse `Ticket`, die Tickets für Fußballspiele repräsentieren kann. Die Klasse soll das Spiel und eine übergreifende Seriennummer speichern.
Versehen Sie die Klasse mit einem Konstruktor, um Instanzen anlegen zu können. Der Konstruktor soll nur das Spiel bekommen, die Seriennummer verwaltet die Klasse selbst und zählt sie für jedes Ticket hoch.
Überschreiben Sie die `to_s`-Methode so, dass man Tickets einfach ausgeben kann.
Sehen Sie eine _statische_ Methode `verkauft` vor, um die aktuell verkaufte Anzahl von Tickets (höchste Seriennummer) auszulesen.
Testen Sie Ihre Klasse, indem Sie Objekte anlegen und ausgeben.
Schreiben Sie eine Methode `produkt`, der man 2, 3, oder 4 Zahlen übergeben kann. Die Methode berechnet dann das Produkt und gibt es zurück. Verwenden Sie _Default Parameter_ um diese Methode zu realisieren.

View File

@ -1,31 +1,11 @@
# Lösung: Klasse deklarieren
# Lösung: Default Parameter
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Ticket
attr_reader :spiel
@@seriennummer = 1
def initialize(spiel)
@spiel = spiel
@seriennummer = @@seriennummer
@@seriennummer += 1
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def produkt(a, b, c = 1, d = 1)
a * b * c * d
end
def to_s
"#{@spiel} [#{@seriennummer}]"
end
def self.verkauft
@@seriennummer
end
end
t1 = Ticket.new('Dortmund-Schalke')
t2 = Ticket.new('Hoffenheim-Stuttgart')
puts t1
puts t2
puts Ticket::verkauft
puts produkt(5, 7)
puts produkt(5, 7, 8)
puts produkt(5, 7, 8, 3)
```

View File

@ -1,5 +1,7 @@
# Default Parameter
# Vererbung
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Methode `produkt`, der man 2, 3, oder 4 Zahlen übergeben kann. Die Methode berechnet dann das Produkt und gibt es zurück. Verwenden Sie _Default Parameter_ um diese Methode zu realisieren.
Schreiben Sie eine Klasse `Mensch`, die den Namen und das Alter eines Menschen speichert. Leiten Sie davon die Klasse `Student` ab, die zusätzlich noch die Matrikelnummer enthält. Sorgen Sie dafür, dass die Objekte bei der Erzeugung korrekt initialisiert werden.
Überschreiben Sie in beiden Klassen sinnvoll die `to_s`-Methode.

View File

@ -1,11 +1,30 @@
# Lösung: Default Parameter
# Lösung: Vererbung
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def produkt(a, b, c = 1, d = 1)
a * b * c * d
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Mensch
attr_reader :name, :alte
def initialize(name, alter)
@name, @alter = name, Integer(alter)
end
puts produkt(5, 7)
puts produkt(5, 7, 8)
puts produkt(5, 7, 8, 3)
def to_s
"#{@name}, Alter: #{@alter}"
end
end
class Student < Mensch
attr_reader :matrikel_nr
def initialize(name, alter, matrikel_nr)
super(name, alter)
@matrikel_nr = matrikel_nr
end
def to_s
super + ", Matrikel-Nr.: #{@matrikel_nr}"
end
end
s = Student.new('Emil Meier', 22, '1822233')
```

View File

@ -1,7 +1,5 @@
# Vererbung
# Keyword-Parameter
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Klasse `Mensch`, die den Namen und das Alter eines Menschen speichert. Leiten Sie davon die Klasse `Student` ab, die zusätzlich noch die Matrikelnummer enthält. Sorgen Sie dafür, dass die Objekte bei der Erzeugung korrekt initialisiert werden.
Überschreiben Sie in beiden Klassen sinnvoll die `to_s`-Methode.
Schreiben Sie eine Methode `greet`, der man Name und Vorname übergeben kann und die den Aufrufer dann mit "Hello" und dem Vornamen, gefolgt vom Nachnamen begrüßt. Die Reihenfolge der Parameter `vorname` und `nachname` sollen beliebig sein. Verwenden Sie deswegen Schlüsselwort-Parameter.

View File

@ -1,30 +1,10 @@
# Lösung: Vererbung
# Lösung: Keyword-Parameter
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Mensch
attr_reader :name, :alte
def initialize(name, alter)
@name, @alter = name, Integer(alter)
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def greet(vorname:, nachname:)
puts "Hello #{vorname} #{nachname}"
end
def to_s
"#{@name}, Alter: #{@alter}"
end
end
class Student < Mensch
attr_reader :matrikel_nr
def initialize(name, alter, matrikel_nr)
super(name, alter)
@matrikel_nr = matrikel_nr
end
def to_s
super + ", Matrikel-Nr.: #{@matrikel_nr}"
end
end
s = Student.new('Emil Meier', 22, '1822233')
greet(vorname: 'Barbara', nachname: 'Liskov')
greet(nachname: 'Liskov', vorname: 'Barbara')
```

View File

@ -1,5 +1,5 @@
# Keyword-Parameter
# Mixin benutzen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Methode `greet`, der man Name und Vorname übergeben kann und die den Aufrufer dann mit "Hello" und dem Vornamen, gefolgt vom Nachnamen begrüßt. Die Reihenfolge der Parameter `vorname` und `nachname` sollen beliebig sein. Verwenden Sie deswegen Schlüsselwort-Parameter.
Schreiben Sie eine Klasse `Squares`, die das Mixin `Enumerable` einbindet und Quadratzahlen beginnend bei 1 bis zu einer im Konstruktor definierten Obergrenze `max` liefert.

View File

@ -1,10 +1,21 @@
# Lösung: Keyword-Parameter
# Lösung: Mixin benutzen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def greet(vorname:, nachname:)
puts "Hello #{vorname} #{nachname}"
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Squares
include Enumerable
def initialize(max)
@max = max
end
greet(vorname: 'Barbara', nachname: 'Liskov')
greet(nachname: 'Liskov', vorname: 'Barbara')
def each
for i in 1..@max
yield i ** 2
end
end
end
s = Squares.new(20)
s.each { |e| puts e }
s.first
```

View File

@ -1,5 +1,7 @@
# Mixin benutzen
# Modul schreiben
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Klasse `Squares`, die das Mixin `Enumerable` einbindet und Quadratzahlen beginnend bei 1 bis zu einer im Konstruktor definierten Obergrenze `max` liefert.
Erstellen Sie ein Modul `Chemie`, das die _Avogadro-Konstante_ (6,02214179 × 10^23) `N_a` und das Molvolumen (22,413996 l/mol) `M_v` enthält. Außerdem soll es eine Methode `volume_o2` enthalten, die für eine gegebene Masse (`m_O`) Sauerstoff das Volumen berechnet. Die Formel hierzu ist `m_O / 32 * M_v`.
Testen Sie das Modul mit eigenen Daten.

View File

@ -1,21 +1,15 @@
# Lösung: Mixin benutzen
# Lösung: Modul schreiben
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Squares
include Enumerable
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
module Chemie
N_a = 6.02214179E23
M_v = 22.413996
def initialize(max)
@max = max
end
def each
for i in 1..@max
yield i ** 2
end
def Chemie.volume_o2(m_O)
m_O / 32 * M_v
end
end
s = Squares.new(20)
s.each { |e| puts e }
s.first
puts Chemie::N_a
puts Chemie::volume_o2(10.0)
```

View File

@ -1,7 +1,11 @@
# Modul schreiben
# Monkey Patch
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Erstellen Sie ein Modul `Chemie`, das die _Avogadro-Konstante_ (6,02214179 × 10^23) `N_a` und das Molvolumen (22,413996 l/mol) `M_v` enthält. Außerdem soll es eine Methode `volume_o2` enthalten, die für eine gegebene Masse (`m_O`) Sauerstoff das Volumen berechnet. Die Formel hierzu ist `m_O / 32 * M_v`.
Schreiben Sie einen Monkey Patch, der die Klasse `String` um die Methode `to_leet` erweitert. Diese Methode gibt den Inhalt des Strings zurück, macht aber in der Rückgabe vorher die folgenden Ersetzungen:
Testen Sie das Modul mit eigenen Daten.
* `a` -> `4`
* `e` -> `3`
* `i` -> `1`
* `o` -> `O`
* `t` -> `7`

View File

@ -1,15 +1,11 @@
# Lösung: Modul schreiben
# Lösung: Monkey Patch
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
module Chemie
N_a = 6.02214179E23
M_v = 22.413996
def Chemie.volume_o2(m_O)
m_O / 32 * M_v
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class String
def to_leet
self.tr('aeiou', '43107')
end
end
puts Chemie::N_a
puts Chemie::volume_o2(10.0)
print "hello leet".to_leet # => h3ll0 l337
```

View File

@ -1,11 +1,5 @@
# Monkey Patch
# Geschachtelte Methoden
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie einen Monkey Patch, der die Klasse `String` um die Methode `to_leet` erweitert. Diese Methode gibt den Inhalt des Strings zurück, macht aber in der Rückgabe vorher die folgenden Ersetzungen:
* `a` -> `4`
* `e` -> `3`
* `i` -> `1`
* `o` -> `O`
* `t` -> `7`
Schreiben Sie eine Klasse `Bomb`. Diese soll eine statische Methode `activate` haben. Erst nach dem Aufruf dieser Methode soll es möglich sein, auf Objekten von `Bomb` die Methode `explode` aufzurufen.

View File

@ -1,11 +1,19 @@
# Lösung: Monkey Patch
# Lösung: Geschachtelte Methoden
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class String
def to_leet
self.tr('aeiou', '43107')
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Bomb
def self.activate
def explode
puts "Booooommmmm"
end
end
end
print "hello leet".to_leet # => h3ll0 l337
b1 = Bomb.new
b2 = Bomb.new
b1.explode # Fehler
Bomb::activate
b1.explode
b2.explode
```

View File

@ -1,5 +1,5 @@
# Geschachtelte Methoden
# Vararg-Methoden
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Klasse `Bomb`. Diese soll eine statische Methode `activate` haben. Erst nach dem Aufruf dieser Methode soll es möglich sein, auf Objekten von `Bomb` die Methode `explode` aufzurufen.
Schreiben Sie eine Ruby-Methode `produkt`, die eine beliebige Anzahl von Werten nimmt, miteinander multipliziert und das Ergebnis zurück gibt. Rufen Sie Ihre Methode danach auf.

View File

@ -1,19 +1,9 @@
# Lösung: Geschachtelte Methoden
# Lösung: Vararg-Methoden
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Bomb
def self.activate
def explode
puts "Booooommmmm"
end
end
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def produkt(*p)
p.reduce { |s, e| s *= e }
end
b1 = Bomb.new
b2 = Bomb.new
b1.explode # Fehler
Bomb::activate
b1.explode
b2.explode
puts produkt(5, 7, 8, 1)
```

View File

@ -1,15 +1,10 @@
# Aufgabenblock 2: Ruby Klassen
# Arrays
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Klassen, Module, Mixins__.
Simulieren Sie ein Kartendeck mit Hilfe von Arrays. Jede Karte wird durch ein Ruby-Symbol repräsentiert das aus zwei Zeichen besteht. Das erste Zeichen repräsentiert die Farbe (P, X, H, K), das zweite den Wert (7, 8, 9, 0, B, D, K, A).
Folgende Themen werden durch die Aufgaben abgedeckt:
* Klassen
* Variablen
* Methoden
* Vererbung
* Modules
* Mixins
* Duck-Typing
* Erzeugen Sie einen vollständigen Kartenstapel mit 32 Karten.
* Mischen Sie die Karten.
* Nehmen Sie 5 Karten von oben und 5 Karten von unten ab und legen Sie sie in einen neuen Stapel
* Mischen Sie die abgenommenen Karten und legen Sie diese wieder auf den Stapel

View File

@ -0,0 +1,28 @@
# Lösung: Arrays
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
stapel = []
for farbe in %w{P X H K}
for wert in %w{7 8 9 0 B D K A}
stapel << (farbe + wert).to_sym
end
end
# Mischen
stapel.shuffle!
# Karten abnehmen
neu = stapel[0..4]
neu << stapel[-5..-1]
stapel -= neu
# Karten mischen
neu.shuffle!
# Karten wieder auf den Stapel legen
stapel << neu
puts neu
puts stapel
```

View File

@ -1,5 +1,14 @@
# Vararg-Methoden
# Callback mit Block
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Ruby-Methode `produkt`, die eine beliebige Anzahl von Werten nimmt, miteinander multipliziert und das Ergebnis zurück gibt. Rufen Sie Ihre Methode danach auf.
Schreiben Sie eine Funktion `rechner`, der man einen Block übergeben kann. `rechner` übergibt dem Block zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
Beispiel:
```ruby
puts rechner(5, 4) { |a, b| a + b }
# -> 18
puts rechner(5, 4) { |a, b| a - b }
# -> 2
```

View File

@ -1,9 +1,11 @@
# Lösung: Vararg-Methoden
# Lösung: Callback mit Block
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def produkt(*p)
p.reduce { |s, e| s *= e }
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def rechner(a, b)
ergebnis = yield a, b
ergebnis * 2
end
puts produkt(5, 7, 8, 1)
puts rechner(5, 4) { |a, b| a + b }
puts rechner(5, 4) { |a, b| a - b }
```

View File

@ -1,10 +1,12 @@
# Arrays
# Callback mit Proc
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Simulieren Sie ein Kartendeck mit Hilfe von Arrays. Jede Karte wird durch ein Ruby-Symbol repräsentiert das aus zwei Zeichen besteht. Das erste Zeichen repräsentiert die Farbe (P, X, H, K), das zweite den Wert (7, 8, 9, 0, B, D, K, A).
Schreiben Sie eine Funktion `rechner`, der man einen Block, ein Lambda oder ein Proc-Objekt übergeben kann. `rechner` übergibt dem Block/Proc/Lambda zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
* Erzeugen Sie einen vollständigen Kartenstapel mit 32 Karten.
* Mischen Sie die Karten.
* Nehmen Sie 5 Karten von oben und 5 Karten von unten ab und legen Sie sie in einen neuen Stapel
* Mischen Sie die abgenommenen Karten und legen Sie diese wieder auf den Stapel
Beispiel:
```ruby
lam = ->(a, b) { a + b }
puts rechner(5, 4, lam) # -> 18
```

View File

@ -1,28 +1,12 @@
# Lösung: Arrays
# Lösung: Callback mit Proc
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
stapel = []
for farbe in %w{P X H K}
for wert in %w{7 8 9 0 B D K A}
stapel << (farbe + wert).to_sym
end
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def rechner(a, b, lam = nil, &block)
lam ||= block
ergebnis = lam.call(a, b)
ergebnis * 2
end
# Mischen
stapel.shuffle!
# Karten abnehmen
neu = stapel[0..4]
neu << stapel[-5..-1]
stapel -= neu
# Karten mischen
neu.shuffle!
# Karten wieder auf den Stapel legen
stapel << neu
puts neu
puts stapel
lam = ->(a, b) { a + b }
puts rechner(5, 4, lam) # -> 18
```

View File

@ -1,14 +1,12 @@
# Callback mit Block
# Closure
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `rechner`, der man einen Block übergeben kann. `rechner` übergibt dem Block zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
Schreiben Sie eine Ruby-Funktion `create_counter`, die ein Proc-Object zurück gibt. Das Proc-Objekt soll bei jedem Aufruf eine aufsteigende Zahl zurückgeben.
Beispiel:
```ruby
puts rechner(5, 4) { |a, b| a + b }
# -> 18
puts rechner(5, 4) { |a, b| a - b }
# -> 2
p = create_counter
puts p.call # -> 1
puts p.call # -> 2
```

View File

@ -1,11 +1,12 @@
# Lösung: Callback mit Block
# Lösung: Closure
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def rechner(a, b)
ergebnis = yield a, b
ergebnis * 2
def create_counter
n = 0 # closure
Proc.new { n += 1 }
end
puts rechner(5, 4) { |a, b| a + b }
puts rechner(5, 4) { |a, b| a - b }
p = create_counter
puts p.call # -> 1
puts p.call # -> 2
```

View File

@ -1,12 +1,19 @@
# Callback mit Proc
# Hashes und Blöcke
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `rechner`, der man einen Block, ein Lambda oder ein Proc-Objekt übergeben kann. `rechner` übergibt dem Block/Proc/Lambda zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
Realisieren Sie einen einfachen _Cache_ mit Hilfe von _Hashes_. Schreiben Sie hierzu eine Klasse `Cache`.
Beispiel:
Die Klasse `Cache` hat eine Methode zum Hinzufügen von Elementen (`add`) und eine zum Auslesen (`[]`), wobei jeweils ein String als Schlüssel verwendet wird.
Wenn ein Element nicht enthalten sein sollte, liefert die Methode `[]` nicht `nil` zurück, sondern ruft einen Block auf, der im Konstruktor der Klasse übergeben wurde. Diese Block beschafft die Daten und gibt sie zurück.
Eine beispielhafte Benutzung sähe dann wie folgt aus:
```ruby
lam = ->(a, b) { a + b }
puts rechner(5, 4, lam) # -> 18
c = Cache.new { |key| "Neuer Wert für key #{key}" }
c.add 'key1', 'value1'
c.add 'key2', 'value2'
puts c['key1'] # -> 'value1'
puts c['key3'] # -> 'Neuer Wert'
```

View File

@ -1,12 +1,19 @@
# Lösung: Callback mit Proc
# Lösung: Hashes und Blöcke
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def rechner(a, b, lam = nil, &block)
lam ||= block
ergebnis = lam.call(a, b)
ergebnis * 2
class Cache
def initialize(&callback)
@data = {}
@callback = callback
end
lam = ->(a, b) { a + b }
puts rechner(5, 4, lam) # -> 18
def add(key, value)
@data[key] = value
end
def [](key)
@data[key] = @callback.call(key) unless @data.has_key?(key)
@data[key]
end
end
```

View File

@ -1,12 +1,10 @@
# Closure
# Hashes
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Ruby-Funktion `create_counter`, die ein Proc-Object zurück gibt. Das Proc-Objekt soll bei jedem Aufruf eine aufsteigende Zahl zurückgeben.
Gegeben sei ein Array mit einigen Begriffen (siehe unten). Bitte schreiben Sie eine Funktion `de_dupe`, die ein solches Array mit Strings bekommt, die Duplikate entfernt und danach das Array sortiert wieder zurück gibt. Die Funktion soll intern mit einem _Hash_ arbeiten.
Beispiel:
```ruby
p = create_counter
puts p.call # -> 1
puts p.call # -> 2
worte = %w{ Bier Schnaps Bier Vodka \
Rum Baileys Rum Bier Vodka Bier Hugo }
```

View File

@ -1,12 +1,14 @@
# Lösung: Closure
# Lösung: Hashes
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def create_counter
n = 0 # closure
Proc.new { n += 1 }
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
worte = %w{ Bier Schnaps Bier Vodka Rum Baileys Rum Bier Vodka Bier Hugo }
def de_dupe(input)
hash = {}
input.each { |e| hash[e] = true }
hash.keys.sort
end
p = create_counter
puts p.call # -> 1
puts p.call # -> 2
puts de_dupe(worte)
```

View File

@ -1,19 +1,5 @@
# Hashes und Blöcke
# Map
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Realisieren Sie einen einfachen _Cache_ mit Hilfe von _Hashes_. Schreiben Sie hierzu eine Klasse `Cache`.
Die Klasse `Cache` hat eine Methode zum Hinzufügen von Elementen (`add`) und eine zum Auslesen (`[]`), wobei jeweils ein String als Schlüssel verwendet wird.
Wenn ein Element nicht enthalten sein sollte, liefert die Methode `[]` nicht `nil` zurück, sondern ruft einen Block auf, der im Konstruktor der Klasse übergeben wurde. Diese Block beschafft die Daten und gibt sie zurück.
Eine beispielhafte Benutzung sähe dann wie folgt aus:
```ruby
c = Cache.new { |key| "Neuer Wert für key #{key}" }
c.add 'key1', 'value1'
c.add 'key2', 'value2'
puts c['key1'] # -> 'value1'
puts c['key3'] # -> 'Neuer Wert'
```
Schreiben Sie eine Methode `leeter`, der man ein Array von Strings übergibt und die ein Array mit den entsprechenden Strings in _"Leet Speak"_ zurück gibt. Verwenden Sie hierzu die `map`-Methode.

View File

@ -1,19 +1,18 @@
# Lösung: Hashes und Blöcke
# Lösung: Map
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Cache
def initialize(&callback)
@data = {}
@callback = callback
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
def leeter(array)
array.map do |e|
e.gsub(/[aeiot]/, { \
'a' => '4', \
'e' => '3', \
'i' => '1', \
'o' => '0', \
't' => '7'})
end
end
def add(key, value)
@data[key] = value
end
def [](key)
@data[key] = @callback.call(key) unless @data.has_key?(key)
@data[key]
end
end
test = %w{ Hello world }
puts leeter(test)
```

View File

@ -1,10 +1,5 @@
# Hashes
# Map und Reduce
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Gegeben sei ein Array mit einigen Begriffen (siehe unten). Bitte schreiben Sie eine Funktion `de_dupe`, die ein solches Array mit Strings bekommt, die Duplikate entfernt und danach das Array sortiert wieder zurück gibt. Die Funktion soll intern mit einem _Hash_ arbeiten.
```ruby
worte = %w{ Bier Schnaps Bier Vodka \
Rum Baileys Rum Bier Vodka Bier Hugo }
```
Schreiben Sie eine Methode `char_count`, der man eine Reihe von Strings übergeben kann und die am Ende die Summer der Anzahl der Zeichen in allen Strings zurück gibt. Verwenden Sie hierzu sowohl die `map`- als auch die `reduce`-Methode.

View File

@ -1,14 +1,12 @@
# Lösung: Hashes
# Lösung: Map und Reduce
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
worte = %w{ Bier Schnaps Bier Vodka Rum Baileys Rum Bier Vodka Bier Hugo }
def de_dupe(input)
hash = {}
input.each { |e| hash[e] = true }
hash.keys.sort
def char_count(array)
counts = array.map { |e| e.length }
counts.reduce(:+)
end
puts de_dupe(worte)
array = %w{ Free Kevin Mitnick }
puts char_count(array)
```

View File

@ -1,5 +1,7 @@
# Map
# Ausnahmen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Methode `leeter`, der man ein Array von Strings übergibt und die ein Array mit den entsprechenden Strings in _"Leet Speak"_ zurück gibt. Verwenden Sie hierzu die `map`-Methode.
Schreiben Sie eine Funktion `division`, die zwei Zahlen dividiert. Die Funktion soll einen `ArgumentError` werfen, wenn einer der Parameter keine Zahl ist. Außerdem soll ein `ZeroDivisionError` geworfen werden, falls versucht wird durch 0 zu dividieren.
Testen Sie die Funktion und fangen Sie die Ausnahmen, um sie auszugeben.

View File

@ -1,18 +1,19 @@
# Lösung: Map
# Lösung: Ausnahmen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
def leeter(array)
array.map do |e|
e.gsub(/[aeiot]/, { \
'a' => '4', \
'e' => '3', \
'i' => '1', \
'o' => '0', \
't' => '7'})
end
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def division(a, b)
raise ArgumentError unless (a.is_a? Numeric) && (b.is_a? Numeric)
raise ZeroDivisionError if b == 0
a / b
end
test = %w{ Hello world }
puts leeter(test)
begin
puts division(1.0, 4.0)
puts division(1.0, 0.0)
puts division('a', 7)
rescue ArgumentError => e
puts e
rescue ZeroDivisionError => e
puts e
end
```

View File

@ -1,12 +1,5 @@
# Aufgabenblock 3: Ruby Container
# Klasse Dir und IO
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Container, Blöcke und Iteratoren__.
Folgende Themen werden durch die Aufgaben abgedeckt:
* Arrays
* Hashes
* Blöcke
* Iteratoren
Schreiben Sie Skript, das mit Hilfe der Klassen `Dir` und `IO` alle Dateien im aktuellen Verzeichnis mit der Endung `.txt` ausgibt. Dabei sollen für jede Zeile und Datei die Zeilennummern vorangestellt werden.

View File

@ -0,0 +1,19 @@
# Lösung: Klasse Dir und IO
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def print(f)
n = 0
puts f, "\n"
IO.foreach(f) do |line|
puts "%4d %s" % [ n, line ]
n += 1
end
puts "\n\n"
end
Dir.foreach('.') do |f|
print f if /.*\.txt$/ =~ f
end
```

View File

@ -1,5 +1,5 @@
# Map und Reduce
# Iteratoren auf Zahlen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Methode `char_count`, der man eine Reihe von Strings übergeben kann und die am Ende die Summer der Anzahl der Zeichen in allen Strings zurück gibt. Verwenden Sie hierzu sowohl die `map`- als auch die `reduce`-Methode.
Schreiben Sie eine Countdown von 10 auf 0. Verwenden Sie dazu die Methode `downto` von `Number`.

View File

@ -1,12 +1,5 @@
# Lösung: Map und Reduce
# Lösung: Iteratoren auf Zahlen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
```ruby
def char_count(array)
counts = array.map { |e| e.length }
counts.reduce(:+)
end
array = %w{ Free Kevin Mitnick }
puts char_count(array)
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
10.downto(0) { |n| puts n }
```

View File

@ -1,7 +1,7 @@
# Ausnahmen
# Quine
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `division`, die zwei Zahlen dividiert. Die Funktion soll einen `ArgumentError` werfen, wenn einer der Parameter keine Zahl ist. Außerdem soll ein `ZeroDivisionError` geworfen werden, falls versucht wird durch 0 zu dividieren.
Schreiben Sie ein Ruby-Programm, dass sich selbst ausgibt. Es darf seinen Quelltext _nicht_ einlesen, sondern nur Ausgabeanweisungen enthalten.
Testen Sie die Funktion und fangen Sie die Ausnahmen, um sie auszugeben.
_Tipp_: Sie werden eine Variable mit dem Programm als String benötigen. In dem String selbst wird sich ein Platzhalter für einen Formatter befinden.

View File

@ -1,19 +1,5 @@
# Lösung: Ausnahmen
# Lösung: Quine
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def division(a, b)
raise ArgumentError unless (a.is_a? Numeric) && (b.is_a? Numeric)
raise ZeroDivisionError if b == 0
a / b
end
begin
puts division(1.0, 4.0)
puts division(1.0, 0.0)
puts division('a', 7)
rescue ArgumentError => e
puts e
rescue ZeroDivisionError => e
puts e
end
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
p = "p = \"%s\"; puts p %% [ p.gsub(/[\"\\\\]/, '\"' => '\\\"', '\\\\' => '\\\\\\\\') ]"; puts p % [ p.gsub(/["\\]/, '"' => '\\"', '\\' => '\\\\') ]
```

View File

@ -1,5 +1,15 @@
# Klasse Dir und IO
# Reguläre Ausdrücke: Match
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie Skript, das mit Hilfe der Klassen `Dir` und `IO` alle Dateien im aktuellen Verzeichnis mit der Endung `.txt` ausgibt. Dabei sollen für jede Zeile und Datei die Zeilennummern vorangestellt werden.
Schreiben Sie eine Ruby-Methode `tag?`, die angibt, ob es sich bei dem übergebenen String um ein HTML-Tag handelt. Verwenden Sie hierzu einen entsprechenden regulären Ausdruck.
Beispiel:
```ruby
tag?("<a href='xx'>") # -> true
tag?("hugo <jjj>") # -> false
tag?("<a href='xx'") # -> false
tag?("<p/>") # -> true
tag?("<p") # -> false
tag?("p>") # -> false
```

View File

@ -1,19 +1,14 @@
# Lösung: Klasse Dir und IO
# Lösung: Reguläre Ausdrücke: Match
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def print(f)
n = 0
puts f, "\n"
IO.foreach(f) do |line|
puts "%4d %s" % [ n, line ]
n += 1
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def tag?(text)
!!(/^<.*?>$/ =~ text)
end
puts "\n\n"
end
Dir.foreach('.') do |f|
print f if /.*\.txt$/ =~ f
end
tag?("<a href='xx'>") # -> true
tag?("hugo <jjj>") # -> false
tag?("<a href='xx'") # -> false
tag?("<p/>") # -> true
tag?("<p") # -> false
tag?("p>") # -> false
```

View File

@ -1,5 +1,13 @@
# Iteratoren auf Zahlen
# Reguläre Ausdrücke: Matching
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Countdown von 10 auf 0. Verwenden Sie dazu die Methode `downto` von `Number`.
Schreiben Sie eine Funktion `reverser`, die bei einem String, der aus zwei Wörtern besteht (durch Leerzeichen getrennt), diese umdreht. Verwenden Sie hierzu einen Regulären Ausdruck.
Beispiel:
```ruby
s = "Ruby Programmierer"
puts reverser(s)
# -> "Programmierer Ruby"
```

View File

@ -1,5 +1,21 @@
# Lösung: Iteratoren auf Zahlen
# Lösung: Reguläre Ausdrücke: Matching
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
10.downto(0) { |n| puts n }
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def reverser(s)
/(.*) (.*)/ =~ s
"#{$2} #{$1}"
end
puts reverser("Ruby Programmierer")
```
Alternative Lösung:
```ruby
def reverser(s)
m = /(.*) (.*)/.match(s)
"#{m[2]} #{m[1]}"
end
puts reverser("Ruby Programmierer")
```

View File

@ -1,7 +1,22 @@
# Quine
# Klassen per Reflection analysieren
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie ein Ruby-Programm, dass sich selbst ausgibt. Es darf seinen Quelltext _nicht_ einlesen, sondern nur Ausgabeanweisungen enthalten.
Schreiben Sie eine Methode `analyze`, der man eine Klasse übergibt und die dann folgende Informationen zu der Klasse ausgibt:
_Tipp_: Sie werden eine Variable mit dem Programm als String benötigen. In dem String selbst wird sich ein Platzhalter für einen Formatter befinden.
* Name der Klasse
* Elternklasse
* Instanzmethoden
* Statische Methoden
* Konstanten
Beispiel:
```console
> analyze(String)
Name: String
Elternklasse: Object
Instanz-Methoden: [:encode, :include?, ...]
Statische-Methoden: [:try_convert]
Konstanten: []
```

View File

@ -1,5 +1,13 @@
# Lösung: Quine
# Lösung: Klassen per Reflection analysieren
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
p = "p = \"%s\"; puts p %% [ p.gsub(/[\"\\\\]/, '\"' => '\\\"', '\\\\' => '\\\\\\\\') ]"; puts p % [ p.gsub(/["\\]/, '"' => '\\"', '\\' => '\\\\') ]
def analyze(clazz)
puts "Name: #{clazz.to_s}"
puts "Elternklasse: #{clazz.superclass}"
puts "Instanz-Methoden: #{clazz.instance_methods}"
puts "Statische-Methoden: #{clazz.singleton_methods}"
puts "Konstanten: #{clazz.constants}"
end
analyze(String)
```

View File

@ -1,14 +1,20 @@
# Aufgabenblock 4: Ruby Typen
# Methoden einer Klasse dynamisch erzeugen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Standard Typen und Reguläre Ausdrücke__.
Schreiben Sie eine Funktion `leet_class`, die zu jeder vorhandenen (nicht geerbten) Instanzmethode eine weitere Methode hinzufügt, die den Namen der ursprünglichen Methode in _Leet Speak_ hat. Die neue Methode muss keine Funktion haben, kann aber auch gerne an die ursprüngliche Methode delegieren.
Folgende Themen werden durch die Aufgaben abgedeckt:
Beispiel:
* Zahlen
* Strings
* Ranges
* Reguläre Ausdrücke
* Ausnahmen
* Input/Output
```ruby
class M
def hello; end
def world; end
end
leet_class(M)
m = M.new
m.h3ll0
m.w0rld
```

View File

@ -0,0 +1,28 @@
# Lösung: Methoden einer Klasse dynamisch erzeugen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def to_leet(s)
s.tr('aeiou', '43107')
end
def leet_class(clazz)
clazz.instance_methods(false).each do |m|
name = m.to_s
leet_name = to_leet(name).to_sym
puts leet_name
clazz.define_method(leet_name) do |*p|
end
end
end
class M
def hello; end
def world; end
end
leet_class(M)
m = M.new
m.h3ll0
m.w0rld
``

View File

@ -1,15 +1,5 @@
# Reguläre Ausdrücke: Match
# Klasse dynamisch erzeugen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Ruby-Methode `tag?`, die angibt, ob es sich bei dem übergebenen String um ein HTML-Tag handelt. Verwenden Sie hierzu einen entsprechenden regulären Ausdruck.
Beispiel:
```ruby
tag?("<a href='xx'>") # -> true
tag?("hugo <jjj>") # -> false
tag?("<a href='xx'") # -> false
tag?("<p/>") # -> true
tag?("<p") # -> false
tag?("p>") # -> false
```
Schreiben Sie eine Funktion `create_class`, der man den die Superklasse übergeben kann. Die Funktion erzeugt dann dynamisch die Klasse und fügt ihr eine Methode `who_am_i` hinzu, die als Text "Ich bin ein Kind von " + den Namen der Superklasse zurückgibt.

View File

@ -1,14 +1,15 @@
# Lösung: Reguläre Ausdrücke: Match
# Lösung: Klasse dynamisch erzeugen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def tag?(text)
!!(/^<.*?>$/ =~ text)
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def create_class(super_class)
Class.new(super_class) do
def who_am_i
puts "Ich bin ein Kind von #{self.class.superclass}"
end
end
end
tag?("<a href='xx'>") # -> true
tag?("hugo <jjj>") # -> false
tag?("<a href='xx'") # -> false
tag?("<p/>") # -> true
tag?("<p") # -> false
tag?("p>") # -> false
Test = create_class(Object)
t = Test.new
t.who_am_i
```

View File

@ -1,13 +1,7 @@
# Reguläre Ausdrücke: Matching
# Methoden dynamisch aufrufen
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `reverser`, die bei einem String, der aus zwei Wörtern besteht (durch Leerzeichen getrennt), diese umdreht. Verwenden Sie hierzu einen Regulären Ausdruck.
Schreiben Sie eine Funktion `crazy_caller`, der man ein Objekt übergeben kann. Die Funktion schaut nach, welche Methoden auf dem Objekt aufrufbar sind und ruft dann alle Methoden auf, die keinen Parameter benötigen.
Beispiel:
```ruby
s = "Ruby Programmierer"
puts reverser(s)
# -> "Programmierer Ruby"
```
Einige Methoden werden einen Fehler werfen, fangen Sie diesen ab.

View File

@ -1,21 +1,27 @@
# Lösung: Reguläre Ausdrücke: Matching
# Lösung: Methoden dynamisch aufrufen
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def reverser(s)
/(.*) (.*)/ =~ s
"#{$2} #{$1}"
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def crazy_caller(obj)
# Methoden suchen
obj.methods.each do |m|
# m enthält ein Symbol mit dem Namen der Methode,
# wir wollen aber das Methoden-Objekt
method = obj.method(m)
begin
# Methode aufrufen, wenn sie keinen Parameter hat
method.call {} if method.arity == 0
rescue
end
end
end
puts reverser("Ruby Programmierer")
```
Alternative Lösung:
```ruby
def reverser(s)
m = /(.*) (.*)/.match(s)
"#{m[2]} #{m[1]}"
class Test
def m1; puts 'm1'; end
def m2; puts 'm2'; end
def m3(a); puts 'm3'; end
def m4(a, b); puts 'm4'; end
end
puts reverser("Ruby Programmierer")
crazy_caller(Test.new)
```

View File

@ -1,22 +1,5 @@
# Klassen per Reflection analysieren
# Eigenclass einer Klasse
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Methode `analyze`, der man eine Klasse übergibt und die dann folgende Informationen zu der Klasse ausgibt:
* Name der Klasse
* Elternklasse
* Instanzmethoden
* Statische Methoden
* Konstanten
Beispiel:
```console
> analyze(String)
Name: String
Elternklasse: Object
Instanz-Methoden: [:encode, :include?, ...]
Statische-Methoden: [:try_convert]
Konstanten: []
```
Fügen Sie der Klasse `Numeric` über deren _Eigenclass_ eine _statische Methode_ `to_binary` hinzu, der man eine Zahl übergibt und diese in binärer Darstellung als String zurück bekommt.

View File

@ -1,13 +1,25 @@
# Lösung: Klassen per Reflection analysieren
# Lösung: Eigenclass einer Klasse
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def analyze(clazz)
puts "Name: #{clazz.to_s}"
puts "Elternklasse: #{clazz.superclass}"
puts "Instanz-Methoden: #{clazz.instance_methods}"
puts "Statische-Methoden: #{clazz.singleton_methods}"
puts "Konstanten: #{clazz.constants}"
class Numeric
class << self
def to_binary(n)
n.to_s(2)
end
end
end
analyze(String)
puts Numeric::to_binary(47)
```
Alternative Lösung:
```ruby
class << Numeric
def to_binary(n)
n.to_s(2)
end
end
puts Numeric::to_binary(47)
```

View File

@ -1,20 +1,10 @@
# Methoden einer Klasse dynamisch erzeugen
# Eigenclass eines Objektes
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `leet_class`, die zu jeder vorhandenen (nicht geerbten) Instanzmethode eine weitere Methode hinzufügt, die den Namen der ursprünglichen Methode in _Leet Speak_ hat. Die neue Methode muss keine Funktion haben, kann aber auch gerne an die ursprüngliche Methode delegieren.
Beispiel:
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie der _Eigenclass_ von `s2` eine _Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
```ruby
class M
def hello; end
def world; end
end
leet_class(M)
m = M.new
m.h3ll0
m.w0rld
s1 = "Hallo"
s2 = "Welt"
```

View File

@ -1,28 +1,14 @@
# Lösung: Methoden einer Klasse dynamisch erzeugen
# Lösung: Eigenclass eines Objektes
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def to_leet(s)
s.tr('aeiou', '43107')
end
s1 = "Hallo"
s2 = "Welt"
def leet_class(clazz)
clazz.instance_methods(false).each do |m|
name = m.to_s
leet_name = to_leet(name).to_sym
puts leet_name
clazz.define_method(leet_name) do |*p|
end
class << s2
def to_leet
self.tr('aeiou', '43107')
end
end
class M
def hello; end
def world; end
end
leet_class(M)
m = M.new
m.h3ll0
m.w0rld
``
puts s2.to_leet
```

View File

@ -1,5 +1,17 @@
# Klasse dynamisch erzeugen
# Macro
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `create_class`, der man den die Superklasse übergeben kann. Die Funktion erzeugt dann dynamisch die Klasse und fügt ihr eine Methode `who_am_i` hinzu, die als Text "Ich bin ein Kind von " + den Namen der Superklasse zurückgibt.
Schreiben Sie ein Modul `Javanator`, das eine Klassen einbinden kann. Durch Aufruf der Methode `javafy` kann die Klasse sich dann die Methode `toString` hinzufügen lassen, die einfach nur `to_s` aufruft.
Beispiel:
```ruby
class Test
include Javanator
Javanator::javafy
end
t = Test.new
t.toString
```

View File

@ -1,15 +1,17 @@
# Lösung: Klasse dynamisch erzeugen
# Lösung: Macro
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def create_class(super_class)
Class.new(super_class) do
def who_am_i
puts "Ich bin ein Kind von #{self.class.superclass}"
end
module Javanator
def Javanator::javafy
def toString; to_s; end
end
end
Test = create_class(Object)
class Test
include Javanator
Javanator::javafy
end
t = Test.new
t.who_am_i
t.toString
```

View File

@ -1,7 +1,22 @@
# Methoden dynamisch aufrufen
# Metaprogrammierung: Die kleine Petze
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Schreiben Sie eine Funktion `crazy_caller`, der man ein Objekt übergeben kann. Die Funktion schaut nach, welche Methoden auf dem Objekt aufrufbar sind und ruft dann alle Methoden auf, die keinen Parameter benötigen.
Schreiben Sie eine Ruby Klasse `Snitch`, deren Objekte man an jede beliebige Ruby-Methode übergeben kann. `Snitch` soll dann auf der Konsole ausgeben, welche Methoden mit welchen Parametern auf ihm aufgerufen wurden.
Einige Methoden werden einen Fehler werfen, fangen Sie diesen ab.
Beispiel:
```ruby
snitch = Snitch.new
puts snitch
```
Ausgabe:
```console
Aufruf von Methode 'to_ary'
mit den Argumenten []
mit den Argumenten {}
und dem Block
Aufruf von Methode 'to_s'
```

View File

@ -1,27 +1,21 @@
# Lösung: Methoden dynamisch aufrufen
# Lösung: Metaprogrammierung: Die kleine Petze
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
def crazy_caller(obj)
# Methoden suchen
obj.methods.each do |m|
# m enthält ein Symbol mit dem Namen der Methode,
# wir wollen aber das Methoden-Objekt
method = obj.method(m)
begin
# Methode aufrufen, wenn sie keinen Parameter hat
method.call {} if method.arity == 0
rescue
end
end
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Snitch
def method_missing(name, *args, **keywords, &block)
puts "Aufruf von Methode '#{name}'"
puts " mit den Argumenten #{args}"
puts " mit den Argumenten #{keywords}"
puts " und dem Block #{block}"
end
class Test
def m1; puts 'm1'; end
def m2; puts 'm2'; end
def m3(a); puts 'm3'; end
def m4(a, b); puts 'm4'; end
def to_s
puts "Aufruf von Methode 'to_s'"
end
crazy_caller(Test.new)
# Weiter Methoden von Object überschreiben. Hier weggelassen.
end
snitch = Snitch.new
puts snitch
```

View File

@ -1,5 +1,10 @@
# Eigenclass einer Klasse
# Singleton Methoden
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Fügen Sie der Klasse `Numeric` über deren _Eigenclass_ eine _statische Methode_ `to_binary` hinzu, der man eine Zahl übergibt und diese in binärer Darstellung als String zurück bekommt.
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie `s2` eine _Singleton Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
```ruby
s1 = "Hallo"
s2 = "Welt"
```

View File

@ -1,25 +1,12 @@
# Lösung: Eigenclass einer Klasse
# Lösung: Singleton Methoden
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
class Numeric
class << self
def to_binary(n)
n.to_s(2)
end
end
s1 = "Hallo"
s2 = "Welt"
def s2.to_leet
self.tr('aeiou', '43107')
end
puts Numeric::to_binary(47)
```
Alternative Lösung:
```ruby
class << Numeric
def to_binary(n)
n.to_s(2)
end
end
puts Numeric::to_binary(47)
puts s2.to_leet
```

View File

@ -1,10 +1,15 @@
# Eigenclass eines Objektes
# Struct
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie der _Eigenclass_ von `s2` eine _Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
Verwenden Sie die Klasse `Struct`, um sehr einfach eine Klasse zur Verwaltung von Studierenden (`Studierender`) zu erzeugen. Ein Studierender hat folgende Eigenschaften:
```ruby
s1 = "Hallo"
s2 = "Welt"
```
* Vorname
* Nachname
* Geburtsdatum
* Matrikelnummer
* Fakultät
Fügen Sie eine `to_s`-Methode zur Klasse hinzu, die nur die Matrikelnummer zurückgibt.
Erzeugen Sie danach ein Objekt von Ihrer Klasse.

View File

@ -1,14 +1,16 @@
# Lösung: Eigenclass eines Objektes
# Lösung: Struct
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
s1 = "Hallo"
s2 = "Welt"
# Klasse (sic!) über Struct erzeugen
Studierender = Struct.new(:vorname, :nachname, :geboren, :matrikel, :fakultaet)
class << s2
def to_leet
self.tr('aeiou', '43107')
# KLasse noch einmal öffnen und Methode hinzufügen
class Studierender
def to_s
matrikel
end
end
puts s2.to_leet
peter = Studierender.new('Peter', 'Meier', '15.03.1998', '123222', 'I')
puts peter
```

View File

@ -13,44 +13,39 @@ Die **Abgabedaten** haben keine Bedeutung, da der Kurs keine Prüfung beinhaltet
| 3. | [String-Formatierung](Assignment_003/readme.md) | **----** |
| 4. | [Parallele Zuweisung](Assignment_004/readme.md) | **----** |
| 5. | [Ranges](Assignment_005/readme.md) | **----** |
| 6. | [Aufgabenblock 1: Ruby Grundlagen](Assignment_006/readme.md) | **----** |
| 7. | [Splat](Assignment_007/readme.md) | **----** |
| 8. | [Symbole](Assignment_008/readme.md) | **----** |
| 9. | [Zugriffsmethoden](Assignment_009/readme.md) | **----** |
| 10. | [Klasse deklarieren](Assignment_010/readme.md) | **----** |
| 11. | [Default Parameter](Assignment_011/readme.md) | **----** |
| 12. | [Vererbung](Assignment_012/readme.md) | **----** |
| 13. | [Keyword-Parameter](Assignment_013/readme.md) | **----** |
| 14. | [Mixin benutzen](Assignment_014/readme.md) | **----** |
| 15. | [Modul schreiben](Assignment_015/readme.md) | **----** |
| 16. | [Monkey Patch](Assignment_016/readme.md) | **----** |
| 17. | [Geschachtelte Methoden](Assignment_017/readme.md) | **----** |
| 18. | [Aufgabenblock 2: Ruby Klassen](Assignment_018/readme.md) | **----** |
| 19. | [Vararg-Methoden](Assignment_019/readme.md) | **----** |
| 20. | [Arrays](Assignment_020/readme.md) | **----** |
| 21. | [Callback mit Block](Assignment_021/readme.md) | **----** |
| 22. | [Callback mit Proc](Assignment_022/readme.md) | **----** |
| 23. | [Closure](Assignment_023/readme.md) | **----** |
| 24. | [Hashes und Blöcke](Assignment_024/readme.md) | **----** |
| 25. | [Hashes](Assignment_025/readme.md) | **----** |
| 26. | [Map](Assignment_026/readme.md) | **----** |
| 27. | [Aufgabenblock 3: Ruby Container](Assignment_027/readme.md) | **----** |
| 28. | [Map und Reduce](Assignment_028/readme.md) | **----** |
| 29. | [Ausnahmen](Assignment_029/readme.md) | **----** |
| 30. | [Klasse Dir und IO](Assignment_030/readme.md) | **----** |
| 31. | [Iteratoren auf Zahlen](Assignment_031/readme.md) | **----** |
| 32. | [Quine](Assignment_032/readme.md) | **----** |
| 33. | [Aufgabenblock 4: Ruby Typen](Assignment_033/readme.md) | **----** |
| 34. | [Reguläre Ausdrücke: Match](Assignment_034/readme.md) | **----** |
| 35. | [Reguläre Ausdrücke: Matching](Assignment_035/readme.md) | **----** |
| 36. | [Klassen per Reflection analysieren](Assignment_036/readme.md) | **----** |
| 37. | [Methoden einer Klasse dynamisch erzeugen](Assignment_037/readme.md) | **----** |
| 38. | [Klasse dynamisch erzeugen](Assignment_038/readme.md) | **----** |
| 39. | [Methoden dynamisch aufrufen](Assignment_039/readme.md) | **----** |
| 40. | [Eigenclass einer Klasse](Assignment_040/readme.md) | **----** |
| 41. | [Eigenclass eines Objektes](Assignment_041/readme.md) | **----** |
| 42. | [Macro](Assignment_042/readme.md) | **----** |
| 43. | [Metaprogrammierung: Die kleine Petze](Assignment_043/readme.md) | **----** |
| 44. | [Aufgabenblock 5: Fortgeschrittene Themen](Assignment_044/readme.md) | **----** |
| 45. | [Singleton Methoden](Assignment_045/readme.md) | **----** |
| 46. | [Struct](Assignment_046/readme.md) | **----** |
| 6. | [Splat](Assignment_006/readme.md) | **----** |
| 7. | [Symbole](Assignment_007/readme.md) | **----** |
| 8. | [Zugriffsmethoden](Assignment_008/readme.md) | **----** |
| 9. | [Klasse deklarieren](Assignment_009/readme.md) | **----** |
| 10. | [Default Parameter](Assignment_010/readme.md) | **----** |
| 11. | [Vererbung](Assignment_011/readme.md) | **----** |
| 12. | [Keyword-Parameter](Assignment_012/readme.md) | **----** |
| 13. | [Mixin benutzen](Assignment_013/readme.md) | **----** |
| 14. | [Modul schreiben](Assignment_014/readme.md) | **----** |
| 15. | [Monkey Patch](Assignment_015/readme.md) | **----** |
| 16. | [Geschachtelte Methoden](Assignment_016/readme.md) | **----** |
| 17. | [Vararg-Methoden](Assignment_017/readme.md) | **----** |
| 18. | [Arrays](Assignment_018/readme.md) | **----** |
| 19. | [Callback mit Block](Assignment_019/readme.md) | **----** |
| 20. | [Callback mit Proc](Assignment_020/readme.md) | **----** |
| 21. | [Closure](Assignment_021/readme.md) | **----** |
| 22. | [Hashes und Blöcke](Assignment_022/readme.md) | **----** |
| 23. | [Hashes](Assignment_023/readme.md) | **----** |
| 24. | [Map](Assignment_024/readme.md) | **----** |
| 25. | [Map und Reduce](Assignment_025/readme.md) | **----** |
| 26. | [Ausnahmen](Assignment_026/readme.md) | **----** |
| 27. | [Klasse Dir und IO](Assignment_027/readme.md) | **----** |
| 28. | [Iteratoren auf Zahlen](Assignment_028/readme.md) | **----** |
| 29. | [Quine](Assignment_029/readme.md) | **----** |
| 30. | [Reguläre Ausdrücke: Match](Assignment_030/readme.md) | **----** |
| 31. | [Reguläre Ausdrücke: Matching](Assignment_031/readme.md) | **----** |
| 32. | [Klassen per Reflection analysieren](Assignment_032/readme.md) | **----** |
| 33. | [Methoden einer Klasse dynamisch erzeugen](Assignment_033/readme.md) | **----** |
| 34. | [Klasse dynamisch erzeugen](Assignment_034/readme.md) | **----** |
| 35. | [Methoden dynamisch aufrufen](Assignment_035/readme.md) | **----** |
| 36. | [Eigenclass einer Klasse](Assignment_036/readme.md) | **----** |
| 37. | [Eigenclass eines Objektes](Assignment_037/readme.md) | **----** |
| 38. | [Macro](Assignment_038/readme.md) | **----** |
| 39. | [Metaprogrammierung: Die kleine Petze](Assignment_039/readme.md) | **----** |
| 40. | [Singleton Methoden](Assignment_040/readme.md) | **----** |
| 41. | [Struct](Assignment_041/readme.md) | **----** |