Question
Comment Ruby autorise-t-il implicitement les méthodes d'accès à une classe en dehors de la classe?
Exemple:
class Candy
def land
homer
end
end
def homer
puts "Hello"
end
Candy.new.land #Outputs Hello
La solution
La définition de "homer" La méthode ajoute la méthode à la classe Object. Il ne s'agit pas de définir une fonction libre.
La classe Candy hérite implicitement de Object et a donc accès aux méthodes de Object. Lorsque vous appelez "homer" dans le " terre " méthode, la résolution de la méthode ne trouve aucune définition dans la classe en cours, passe à la super-classe, trouve la méthode que vous avez ajoutée à Object et l’appelle.
Autres conseils
Un moyen simple de savoir ce qui se passe
-
Quelles classes / modules sont recherchés pour résoudre les méthodes utilisées dans les objets Candy?
p Candy.ancestors # = > [Candy, Objet, Noyau]
-
Candy a-t-elle une méthode appelée homer?
p Candy.instance_methods (false) .grep ("homer") # = > []
p Candy.private_instance_methods (false) .grep ("homer") # = > []
-
OK Candy n'a aucune méthode appelée 'homer'.
-
Et ensuite, dans la chaîne de recherche (voir 1) = > "Objet"
-
Object a-t-il une méthode appelée "homer"? ? p Object.instance_methods (false) .grep ("homer") # = > []
p Object.private_instance_methods (false) .grep ("homer") # = > ["homer"]
Candy a dans sa chaîne de recherche Object qui utilise à son tour une méthode d'instance privée "homer". donc la résolution de la méthode réussit
La déclaration def définit toujours la méthode dans la classe de ce que self se trouve au point de définition
-
Qu'est-ce que self juste avant que homer soit défini?
p self # = > principale def homer met " Bonjour " fin
-
Alors, quel est son type?
p self.class # = > Objet
C’est pourquoi homer se termine sur Objet
Techniquement, la définition de la méthode homer
est en fait sur le module Kernel
qui est mélangé dans Object
, et non sur < code> Object directement. Ainsi, lorsque homer
n'est pas une variable locale ou une méthode d'instance définie sur Candy
, la chaîne d'héritage de la méthode Ruby est suivie via Objet
, puis sur le module Kernel
mélangé, puis ce code est exécuté.
Modifier: Désolé, je ne sais pas pourquoi j'ai pensé cela. Il semble que la méthode vit réellement sur Object
. Pas sûr que cela fasse trop de différence dans la pratique, mais j'aurais dû confirmer certaines choses avant de poster.
Ruby n’a pas de fonctions flottantes. Chaque méthode appartient à un objet. Les méthodes que vous def
au niveau supérieur deviennent en réalité des méthodes d'instance de la classe Object
. Parce que tout est un Object
à un certain niveau, tous les objets ont accès aux méthodes d'instance de Object
.