In dieser Ausgabe von ’Ruby is Magic’ stellen wir euch das Schlüsselwort 'self' vor und damit verbunden gibt es auch eine Einführung in das Ruby Objektmodell.
3. self
self ist ein Schlüsselwort
self zeigt immer auf das “aktuelle” Objekt
self ist abhängig vom Kontext
self ist der Default-Empfänger von Nachrichten
Montag, 20. Februar 12
4. self ändern
self = Object.new
Montag, 20. Februar 12
5. self ändern
self = Object.new
;)
SyntaxError: Can't change the value of self
Montag, 20. Februar 12
6. self ändern
self ändert sich immer dann, wenn der Kontext sich ändert
Und das passiert z.B. bei
einem Methodenaufruf
einer Klassen oder Modul-Definition
bei der Verwendung von instance_eval, class_eval & co
Montag, 20. Februar 12
7. class Pony
def visit(other_pony)
puts "#{self} is on a visit."
other_pony.is_pleased
end
def is_pleased
puts "#{self} is pleased about a visit."
end
end
Pony.new("Applejack").visit Pony.new("Pinkie Pie")
=> #<Pony:Applejack> is on a visit.
=> #<Pony:Pinkie Pie> is pleased about a visit.
Montag, 20. Februar 12
8. class & module
class Pony
puts self
def work
puts self
end
end
=> Pony
Pony.new.work
=> #<Pony:0x106da8368>
Montag, 20. Februar 12
10. class_eval & instance_eval
es gibt instance_eval und class_eval / module_eval
instance_eval
instance_eval lässt sich durch class_eval äquivalent verwenden
class_eval / module_eval
führt Code (String oder Block) im Kontext des Empfängers aus
self wird innerhalb des Blocks auf den Empfänger geändert
Montag, 20. Februar 12
11. class Pony; end
Pony.class_eval do
puts self
def work
puts "#{self} is working!"
end
end
=> Pony
Pony.new.work
=> #<Pony:0x10bc98a68> is working!
Montag, 20. Februar 12
12. class Pony
private
def age
"Don't let anyone know!"
end
end
twilight_sparkle = Pony.new
puts twilight_sparkle
=> #<Pony:0x10ba7b690>
twilight_sparkle.instance_eval do
puts self
puts age
end
=> #<Pony:0x10ba7b690>
=> Don't let anyone know!
Montag, 20. Februar 12
13. Fun fact #1
private Methoden sind nur mit
implizitem Empfänger zulässig!
class Pony
def want_to_know_age!
self.age
end
Pony.new.want_to_know_age!
private
def age NoMethodError: private method ‘age’
"Don't let anyone know!"
called for #<Pony:0x00…d8>
end
end
Montag, 20. Februar 12
15. class Ranking
def initialize(items)
@items = items
end
def rank!
@items.each do |item|
# ... perform a secret ranking here
end
end
def size
@item.size
end
ranking = Ranking.new([1,2,3,4])
def each(&block) ranking.rank!
@item.each(&block)
end
end
Montag, 20. Februar 12
16. Singleton Methods
ranking = [1,2,3,4] Singleton Methods sind Methoden,
die nur auf einer Objektinstanz
def ranking.rank! definiert sind
self.each do |item|
# perform ranking Andere Instanzen der gleichen
end Klasse, besitzen diese Methode nicht
end
Sie erweitern also eine spezifische
ranking.rank! Objektinstanz
Montag, 20. Februar 12
20. Fun fact #2
Class Methods sind
Singleton Methods!
class Ranking Klassen sind Objekte, von der Klasse Class
def self.default_score
Daher besitzen sie ebenfalls Singleton Methods
23
end Man vergleiche...
end
def ranking.rank!; … end
def Ranking.default_score
Montag, 20. Februar 12
21. Methoden in Ruby
class Ranking
def rank!; end Methode für Instanzen
def self.default_score; end Methode für self (also Ranking)
end
Montag, 20. Februar 12
23. Ruby Object Model
BasicObject
superclass
Object
User
#<User>
Montag, 20. Februar 12
24. Ruby Object Model
BasicObject
Object
superclass
Module
User Class
#<User>
Montag, 20. Februar 12
25. Was hast das mit self zu
tun? Oder mit Methoden?
pinkie_pie = Pony.new
def pinkie_pie.partey
puts "PARTEY!!"
end
puts Pony.instance_methods.include? :partey
# => false
puts pinkie_pie.methods.include? :partey
# => true
Woher kommt #partey?!
Montag, 20. Februar 12
26. Introducing
Singleton Class
Montag, 20. Februar 12
27. Singleton Class
Jedes Objekt hat seine eigene Meta Klasse, oder auch Singleton Class
Instanz-Variablen (Zustand) lebt in Objekten/Instanzen
Methoden (Verhalten) leben in Klassen/Modulen
Daher muss es für jedes Objekt eine eigene Klasse geben!
Montag, 20. Februar 12
28. Klassen, Singleton Classes,
Objects....?!
User
superclass
class #<Class:#<User:0x2A>>
singleton
class
#<User:0x2A>
Montag, 20. Februar 12
29. Singleton Class explizit
machen
singleton_klass = (class << Ranking; self; end)
singleton_klass = Ranking.singleton_class # 1.9
class Ranking
class << self
def singleton_class
return self
end
end
end
Montag, 20. Februar 12
30. Methoden finden in Ruby
Object
class User
def self.default_location Singleton Class von
"Earth" #<Class:User>
end
der User Klasse
end
User
hubert = User.new
def hubert.resarch
#<Class:#<User>> Singleton Class von
# researching ...
end
hubert
#<User>
Montag, 20. Februar 12
31. Fun Fact #3
Ranking.singleton_class.class_eval {}
==
Ranking.instance_eval {}
Montag, 20. Februar 12
32. self hängt vom Kontext ab
Methoden leben in Modulen,
Variablen in Objektinstanzen
Alle(!) Objektinstanzen haben
Singleton Classes
Montag, 20. Februar 12
35. Was passiert hier?!
class MyClass
def outer_method
puts "outer"
def inner_method NoMethodError: undefined method
puts "inner" `inner_method' for #<Bar:0x00…68>
end
end
end
MyClass.new.inner_method
Montag, 20. Februar 12
36. Was passiert hier?!
class MyClass obj = MyClass.new
def outer_method obj.outer_method
puts "outer" # => outer
def inner_method obj.inner_method
puts "inner" # => inner
end
end
end Hint: Was ist self?
Montag, 20. Februar 12