Comment est-il possible que je puisse avoir des variables d'instance dans un module même si je ne peux pas créer une instance du module? Quel serait le but de @stack
dans le module Stacklike
ci-dessous?
module Stacklike
def stack
@stack ||= []
end
end
Considérez la variable d'instance comme quelque chose qui existera dans n'importe quelle classe qui inclut votre module, et les choses ont un peu plus de sens:
module Stacklike
def stack
@stack ||= []
end
def add_to_stack(obj)
stack.Push(obj)
end
def take_from_stack
stack.pop
end
end
class ClownStack
include Stacklike
def size
@stack.length
end
end
cs = ClownStack.new
cs.add_to_stack(1)
puts cs.size
affichera "1"
Voir ci-dessous:
p Ruby_VERSION
module Stacklike
def stack
@stack ||= []
end
def add_to_stack(obj)
stack.Push(obj)
end
def take_from_stack
stack.pop
end
end
class A
include Stacklike
end
a = A.new
p a.instance_variables #<~~ E
p a.instance_variable_defined?(:@stack) #<~~ A
a.add_to_stack(10) #<~~ B
p a.instance_variable_defined?(:@stack) #<~~ C
p a.instance_variables #<~~ D
Sortie:
"1.9.3"
[]
false
true
[:@stack]
Explication: Oui, les variables d'instance Module
sont présentes dans le class
lorsque vous les include
dans la classe. Mais vous pouvez voir que p a.instance_variable_defined?(:@stack)
affiche false
car @stack
N'est toujours pas défini tant que A . Au point B J'ai défini la variable d'instance @stack. Ainsi, l'instruction au point C , sort comme true
. Signifie que les variables d'instance de module ne sont pas créées par le module lui-même, mais cela peut être fait par les instances de class
si class
incluait ce module. L'instruction dans E affiche []
Comme toujours ce point, la variable d'instance n'a pas été définie, mais si vous voyez la sortie pour la ligne D , il est prouvé que @stack
est à l'intérieur de l'objet a
de class A
.
Pourquoi une telle conception?
Il s'agit de la conception ou parfois des exigences. Supposons que l'on vous ait demandé d'écrire un code d'opération de pile qui sera utilisé par deux sociétés de réservation de billets, dites A
et B
. Maintenant, A
ont une politique de pile pour leurs clients, mais ils ont également plus de formalités à ce sujet. La société B
utilise également une politique de pile avec ses propres formalités, différente de A
. Ainsi, en cas de conception d'une opération Stack
à l'intérieur de class A
Et class B
, Meilleure idée de l'écrire dans un endroit commun, comme A
et B
ont cette fonctionnalité en commun. À l'avenir, si une autre société C
vient à vous, vous pouvez également utiliser ce module dans sa classe, sans réécrire la même fonctionnalité pour chaque A
, B
et C
. Il peut y avoir plus de réflexions mais j'espère que cela vous aidera à répondre vous-même pour votre dernière partie des questions.
C'est tout sur le concept. J'espère que cela aide.
À votre santé!!
Lorsque vous incluez un module dans une classe, toutes ses méthodes d'instance sont effectivement "collées" dans la classe Host. Donc si vous avez:
class Lifo
include Stacklike
end
l = Lifo.new
l.add_to_stack(:widget)
l
a maintenant une variable d'instance @stack
, importé de Stacklike
.
Lorsque vous incluez le module Stacklike dans une autre classe, cette variable d'instance sera disponible comme si elle avait été définie dans cette classe. Cela vous donne la possibilité de définir et de gérer les variables d'instance de la classe de base à partir du module lui-même.