J'étudie pour l'acquisition d'or rubis J'ai changé ma compréhension du super et je voulais le partager.
Tout d'abord, quel type de résultat sera produit lorsque le code suivant est exécuté?
module M
def foo
super
puts "M#foo"
end
end
class C2
def foo
puts "C2#foo"
end
end
class C < C2
def foo
super
puts "C#foo"
end
include M
end
C.new.foo
Option 1
C2#foo C#foo
Option 2
C2#foo M#foo C#foo
Option 3
L'erreur s'affiche
J'ai toujours pensé que c'était 1. Au fait, la bonne réponse est «option 2» Si vous le comprenez correctement et y répondez correctement, vous n'avez plus besoin de chercher. Merci d'avoir regardé jusqu'à présent.
Tout d'abord, comment ai-je choisi l'option 1
"Méthode foo de classe C, hmm hmm" "Oh, super? Il suffit de regarder la classe des parents foo." "Je vois, la réponse est 1!"
C'est comme ça. Je pensais qu'il ne serait pas appelé lorsque j'ai inclus le module.
Apprenons à connaître la super classe. Tout d'abord, une brève description de super décrit dans le Manuel de référence
super appelle la méthode que la méthode actuelle remplace
Je vois, cela ne semble pas appeler une méthode de superclasse. Utilisons maintenant la méthode des ancêtres.
##réduction
class C < C2
def foo
super
puts "C#foo"
end
include M
self.ancestors #=> [C, M, C2, Object, Kernel, BasicObject]
end
C.new.foo
ancêtres est une méthode qui montre l'ordre de recherche des méthodes de manière simple. Par exemple, lorsque la méthode foo est exécutée, la méthode C foo est recherchée, et sinon, le M foo ... est recherché.
Maintenant, regardons à nouveau le code en question.
module M
def foo
super #Se référer à foo dans C2
puts "M#foo"
end
end
class C2
def foo
puts "C2#foo"
end
end
class C < C2
def foo
super #Se référer au toto de M
puts "C#foo"
end
include M
self.ancestors #=> [C, M, C2, Object, Kernel, BasicObject]
end
C.new.foo
#=> C2#foo
#=> M#foo
#=> C#foo
Si vous étudiez pour des qualifications, vous approfondirez votre compréhension, donc si vous avez peu d'expérience pratique, vous pouvez essayer d'étudier.
Recommended Posts