1. Design Patterns in Ruby
Sven Pfleiderer
HdM Stuttgart, Medieninformatik Bachelor
20. Mai 2009
2. 1 Duck Typing
Problemstellung
Beispiel
2 Monkey Patching
Problemstellung
Beispiele
3 Higher-order Functions
Was sind Higher-order Functions?
Beispiele
4 Lizenz
Lizenz
3. 1. Duck Typing Problemstellung
Duck Typing
Sven Pfleiderer Design Patterns in Ruby
4. 1. Duck Typing Problemstellung
Problemstellung
• Ruby ist eine dynamisch typisierte Programmiersprache
• Referenzen können während Laufzeit unterschiedliche Objekttypen
annehmen
• Ruby besitzt Mixins
• Woran “weiss” eine Methode welche Objekte übergeben werden
dürfen?
Sven Pfleiderer Design Patterns in Ruby
5. 1. Duck Typing Problemstellung
Lösung
• Vorhandene Eigenschaften und Methoden bestimmen Gültigkeit
• “If it walks like a duck and quacks like a duck, I would call it a duck”
• Es interessieren nur verwendete Methoden und Eigenschaften statt
Vererbungshierarchie
Sven Pfleiderer Design Patterns in Ruby
6. 1. Duck Typing Beispiel
Beispielklassen
1 c l a s s Duck
2 def quack
3 puts quot; I quack ! quot;
4 end
5 def w a l k
6 puts quot; I w a d d l e l i k e a duck ! quot;
7 end
8 end
9 c l a s s Human
10 def quack
11 puts quot; I can i m m i t a t e a duck ! quot;
12 end
13 def w a l k
14 puts quot; I w a l k l i k e a human ! quot;
15 end
16 end
Sven Pfleiderer Design Patterns in Ruby
7. 1. Duck Typing Beispiel
Verwendung der Objekte
1 def t e s t e r ( duck )
2 duck . quack ( )
3 duck . w a l k ( )
4 end
5
6 p u t s quot;−−−−−− Duck −−−−−−−quot;
7 t e s t e r ( Duck . new )
8 p u t s quot;−−−−−− Human −−−−−−−quot;
9 t e s t e r ( Human . new )
Sven Pfleiderer Design Patterns in Ruby
8. 1. Duck Typing Beispiel
Ausführung
1−−−−−− Duck −−−−−−−
2 I quack !
3 I w a d d l e l i k e a duck !
4
5−−−−−− Human −−−−−−−
6 I can i m m i t a t e a duck !
7 I w a l k l i k e a human !
Sven Pfleiderer Design Patterns in Ruby
9. 2. Monkey Patching Problemstellung
Monkey Patching
Sven Pfleiderer Design Patterns in Ruby
10. 2. Monkey Patching Problemstellung
Problemstellung
Man möchte
• bestehende Klassen um Methoden erweitern
• bestehende Methoden von Klassen verändern
• bestimmte Objekte mit zusätzlichen Methoden ausstatten
• Fehler in vorhandenen Bibliotheken reparieren ohne auf einen
offiziellen Fix warten zu müssen
Sven Pfleiderer Design Patterns in Ruby
11. 2. Monkey Patching Beispiele
Einfaches Beispiel
1 class String
2 def f o o
3 puts s e l f + quot; sagt foo quot;
4 end
5 def b a r
6 puts s e l f + quot; sagt bar quot;
7 end
8 end
Sven Pfleiderer Design Patterns in Ruby
12. 2. Monkey Patching Beispiele
Angewandtes Beispiel
1 r e q u i r e ’ net / http ’
2 require ’ uri ’
3
4 c l a s s URI : : HTTP
5
6 def s h o r t e n _ u r l
7 api_url = quot; http :// b i t . ly / api quot;
8 r e s = Net : : HTTP . p o s t _ f o r m (
9 URI . p a r s e ( a p i _ u r l ) , { ’ u r l ’=> s e l f }
10 )
11 r e t u r n URI . p a r s e ( r e s . body )
12 end
13
14 end
Sven Pfleiderer Design Patterns in Ruby
13. 2. Monkey Patching Beispiele
Ausführung
1 # erstes Beispiel
2 >> quot; Der Patchmonkey quot; . f o o
3 Der Patchmonkey s a g t f o o
4
5 >> quot; Die Typente quot; . b a r
6 Die Typente s a g t b a r
7
8 # zweites Beispiel
9 >> u r i = URI . p a r s e (
10 quot; h t t p : / / b l o g . r o o t h a u s e n . de quot;
11 ) . shorten_url
12
13 >> u r i . to_s
14 => quot; h t t p : / / b i t . l y /2BTVbKquot;
Sven Pfleiderer Design Patterns in Ruby
14. 2. Monkey Patching Beispiele
Patchen von erstellten Objeten
1 t x t = quot; Patchmonkey quot;
2
3 def t x t . h e l l o
4 puts s e l f + quot; sagt h a l l o quot;
5 end
6
7 >> t x t . h e l l o
8 Patchmonkey s a g t h a l l o
Sven Pfleiderer Design Patterns in Ruby
15. 3. Higher-order Functions Was sind Higher-order Functions?
Higher-order Functions
Sven Pfleiderer Design Patterns in Ruby
16. 3. Higher-order Functions Was sind Higher-order Functions?
Was sind Higher-order Functions eigentlich?
• Funktionen sind selbst Werte und werden als solche beandelt
• Können anderen Funktionen übergeben werden
• Können von anderen Funktionen zurück gegeben werden
• Können Variablen zugewiesen werden
Sven Pfleiderer Design Patterns in Ruby
17. 3. Higher-order Functions Was sind Higher-order Functions?
Wie bitte?
Demo oder weitere Slides?
Sven Pfleiderer Design Patterns in Ruby
18. 3. Higher-order Functions Beispiele
Aufruf und Rückgabe
1 >> b l o c k = lambda { | v a r i a b l e |
2 p u t s quot; H i e r r u f t jemand quot; + v a r i a b l e
3 }
4
5 => #<Proc : 0 x b 7 a fd 6 1 c @ ( i r b ) :3>
6
7 >> b l o c k . c a l l ( quot; h a l l o quot; )
8
9 H i e r r u f t jemand h a l l o
Sven Pfleiderer Design Patterns in Ruby
19. 3. Higher-order Functions Beispiele
Methoden, die HO-Functions erwarten
1 >> 5 . t i m e s { | x |
2 p u t s quot; H a l l o Nr . quot; + x . to_s
3 }
4
5 Hallo Nr . 0
6 Hallo Nr . 1
7 Hallo Nr . 2
8 Hallo Nr . 3
9 Hallo Nr . 4
Sven Pfleiderer Design Patterns in Ruby
20. 3. Higher-order Functions Beispiele
Auflisten einer HashMap
1 >> hashmap = { quot; a quot; => 1 , quot; b quot; => 2 , quot; c quot; => 3}
2
3 >> hashmap . e a c h { | key , v a l u e |
4 p u t s quot;#{k e y } e n t s p r i c h t #{v a l u e } quot;
5 }
6
7 a entspricht 1
8 b entspricht 2
9 c entspricht 3
Sven Pfleiderer Design Patterns in Ruby
21. 3. Higher-order Functions Beispiele
Realworld Code: Rubinious
1 def t i m e s
2 i = 0
3 while ( i < s e l f )
4 yield ( i )
5 i += 1
6 end
7 return s e l f
8 end
9 def u p t o ( v a l )
10 i = self
11 w h i l e ( i <= v a l )
12 yield ( i )
13 i += 1
14 end
15 return s e l f
16 end
Sven Pfleiderer Design Patterns in Ruby
22. 4. Lizenz Lizenz
Lizenz: Creative Commons BY-SA 3.0
Sven Pfleiderer Design Patterns in Ruby