2010-12-13 27 views
1

J'apprends le rubis et c'est le cas que j'ai.Ruby singleton de stdlib. Comment tuer une instance

require 'singleton' 
class Lab 
    include Singleton 
    def initialize 
    puts 'initializing' 
    end 
end 

l1 = Lab.instance 
l2 = Lab.instance 

Même si j'ai fait Lab.instance deux fois, je reçois le message "initialisation" une seule fois. Cela signifie que Singleton fonctionne. Génial!

Les rails en mode développement suppriment toutes les constantes en utilisant const_remove, de sorte qu'à la prochaine requête, les modèles et les contrôleurs sont rechargés.

Je veux essayer quelque chose de similaire ici. Je veux tuer à la fois l1 et l2 de sorte que lorsque je fais Lab.instance une nouvelle instance est créée et que je reçois le message "initialisation".

Existe-t-il un moyen de réaliser ce que je demande?

Merci

Répondre

1

Ceci est juste une idée, mais comment implémenter votre propre module singleton? Il ne vous offrira pas la même «sécurité» que le Singleton normal, mais il pourrait être exactement ce dont vous avez besoin.

+0

rouler vos propres trucs est toujours là comme le dernier recours. Merci pour la suggestion et pour l'exemple de code. –

0

Si vous avez besoin d'une nouvelle instance de votre singleton (par exemple, pour jouer avec elle lors d'un test sans affecter les autres tests), vous pouvez utiliser une sous-classe anonyme:

Lab.instance # This writes "initializing" 

MyLab = Class.new(Lab) 

MyLab.instance # This writes "initializing" 
MyLab.instance # This writes nothing 

Si vous vraiment pour réinitialiser votre singleton, vous pouvez faire ce qui suit, mais vous entrez dans la zone d'avertissement , il ne fait pas partie de l'API publique:

Lab.instance # This writes "initializing" 

# Do it at your own risks 
Singleton.__init__(Lab) 

Lab.instance # This writes "initializing" 
Lab.instance # This writes nothing 
1

le Singleton mix-in utilise un assez simple mécanisme que vous pouvez facilement ré-implémenter. Si vous regardez son noyau, vous verrez qu'il utilise une variable d'instance nommée @singleton__instance__ pour la mise en cache. Ainsi, la réinitialisation de cette variable devrait faire l'affaire. Ainsi, si vous essayez d'ajouter cette méthode de classe à votre classe:

def self.reset 
    @singleton__instance__ = nil 
end 

Vous pouvez faire:

l1 = Lab.instance #=> initializing 
l2 = Lab.instance #=> nothing 
Lab.reset 
l3 = Lab.instance #=> initializing 
l4 = Lab.instance #=> nothing