Ruby is Magic - Episode #8: self
-
Upload
dirk-breuer -
Category
Technology
-
view
571 -
download
0
description
Transcript of Ruby is Magic - Episode #8: self
Ruby
#8“self”
Montag, 20. Februar 12
It’s all about (my) self!
Montag, 20. Februar 12
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
self
Montag, 20. Februar 12
self ändern
self = Object.new
Montag, 20. Februar 12
self ändern
self = Object.new
SyntaxError: Can't change the value of self
;)
Montag, 20. Februar 12
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
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." endend
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
class & moduleclass Pony puts self def work puts self endend
Pony.new.work
=> #<Pony:0x106da8368>
=> Pony
Montag, 20. Februar 12
class_eval & instance_eval
Montag, 20. Februar 12
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
class Pony; end
Pony.class_eval do puts self def work puts "#{self} is working!" endend
=> Pony
Pony.new.work
=> #<Pony:0x10bc98a68> is working!
Montag, 20. Februar 12
class Pony private def age "Don't let anyone know!" endend
twilight_sparkle = Pony.newputs twilight_sparkle
=> #<Pony:0x10ba7b690>
twilight_sparkle.instance_eval do puts self puts ageend
=> #<Pony:0x10ba7b690>=> Don't let anyone know!
Montag, 20. Februar 12
Fun fact #1
private Methoden sind nur mitimplizitem Empfänger zulässig!
NoMethodError: private method ‘age’ called for #<Pony:0x00…d8>
class Pony def want_to_know_age! self.age end private def age "Don't let anyone know!" endend
Pony.new.want_to_know_age!
Montag, 20. Februar 12
It’s all about methods!
Montag, 20. Februar 12
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
def each(&block) @item.each(&block) endend
ranking = Ranking.new([1,2,3,4])ranking.rank!
Montag, 20. Februar 12
Singleton Methods
ranking = [1,2,3,4]
def ranking.rank! self.each do |item| # perform ranking endend
ranking.rank!
Singleton Methods sind Methoden, die nur auf einer Objektinstanz definiert sind
Andere Instanzen der gleichen Klasse, besitzen diese Methode nicht
Sie erweitern also eine spezifische Objektinstanz
Montag, 20. Februar 12
Benutzt du regelmäßig Singleton Methods?
Montag, 20. Februar 12
Bestimmt!
Montag, 20. Februar 12
Wetten? ;)
Montag, 20. Februar 12
Klassen sind Objekte, von der Klasse Class
Daher besitzen sie ebenfalls Singleton Methods
Man vergleiche...
class Ranking def self.default_score 23 endend
def ranking.rank!; … end
def Ranking.default_score
Class Methods sindSingleton Methods!
Fun fact #2
Montag, 20. Februar 12
Methoden in Ruby
class Ranking
def rank!; end
def self.default_score; end
end
Methode für Instanzen
Methode für self (also Ranking)
Montag, 20. Februar 12
Ruby Object Model
Montag, 20. Februar 12
Ruby Object Model
User
Object
BasicObjectsu
perc
lass
#<User>
Montag, 20. Februar 12
Ruby Object Model
User
Object
BasicObject
supe
rcla
ss
Module
Class
#<User>
Montag, 20. Februar 12
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# => falseputs pinkie_pie.methods.include? :partey# => true
Woher kommt #partey?!Montag, 20. Februar 12
IntroducingSingleton Class
Montag, 20. Februar 12
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
Klassen, Singleton Classes, Objects....?!
User
#<User:0x2A>
#<Class:#<User:0x2A>>
superclass
class
singletonclass
Montag, 20. Februar 12
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 endend
Montag, 20. Februar 12
Methoden finden in Ruby
User
Object
#<User>
#<Class:#<User>>
#<Class:User>
Singleton Class von hubert
Singleton Class von der User Klasse
class User def self.default_location "Earth" endend
hubert = User.new
def hubert.resarch # researching ...end
Montag, 20. Februar 12
Fun Fact #3
Ranking.singleton_class.class_eval {}
==
Ranking.instance_eval {}
Montag, 20. Februar 12
self hängt vom Kontext ab
Methoden leben in Modulen, Variablen in Objektinstanzen
Alle(!) Objektinstanzen haben Singleton Classes
Montag, 20. Februar 12
One More Thing …
Montag, 20. Februar 12
Frage!!
Montag, 20. Februar 12
Was passiert hier?!class MyClass
def outer_method puts "outer"
def inner_method puts "inner" end end
end
MyClass.new.inner_method
NoMethodError: undefined method `inner_method' for #<Bar:0x00…68>
Montag, 20. Februar 12
Was passiert hier?!
class MyClass
def outer_method puts "outer"
def inner_method puts "inner" end end
end
obj = MyClass.new
obj.outer_method# => outer
obj.inner_method# => inner
Hint: Was ist self?Montag, 20. Februar 12
Thanks! Q & A?
Dirk Breuer / @railsbros_dirk
Sebastian Cohnen / @tisba
?
“My
Little
Pon
y” ©
Has
bro
Stud
ios
and
DHX
Med
ia V
anco
uver
rubyismagic.deMontag, 20. Februar 12