2010-10-28 4 views
4

Disons que j'ai une classe logger qui a un attribut pointant vers un fichier ouvert. Ce fichier devrait être ouvert jusqu'à ce que cette classe ne soit plus utilisée. Quelque chose comme:Meilleures pratiques pour libérer des objets dans ruby ​​

class MyLogger 
    attr_accessor :log_file 
    def initialize 
    @log_file = File.new('my_log_file_name.log','w') 
    end 

    def finalize(id) 
    @log_file.close 
    end 
end 

Comment puis-je m'assurer que lorsque je n'utiliserai plus cette instance, le gestionnaire de fichiers sera fermé? Ive a essayé cela, mais sans effet:

l = MyLogger.new 
l = nil 
ObjectSpace.garbage_collect 

Après cela, si je tente de supprimer le fichier, il renvoie une erreur indiquant que le fichier est utilisé.

Répondre

3

Fermez simplement le handle de fichier via un appel de méthode. Cela n'a pas vraiment de sens de le faire d'une autre façon, surtout en attendant le garbage collector. Si vous savez que vous en avez fini, faites votre nettoyage à ce moment-là.

+4

Vous pourriez avoir une méthode comme 'File.open', qui prend un bloc et gère l'ouverture et la fermeture de la poignée de fichier pour vous. – Chuck

0

Si vous devez libérer des ressources d'un objet, faites-le explicitement. J'ai trouvé this sample source code utile.

0

Étant donné que le garbage collector Ruby s'exécute à des moments imprévisibles, il est impossible de savoir quand le code destructeur s'exécutera. Il peut être préférable d'ouvrir et de fermer le fichier à chaque fois au cours d'un seul appel de méthode.

0

Avez-vous besoin d'avoir le fichier journal ouvert tout le temps? Vous pouvez ouvrir/écrire/fermer lorsque vous souhaitez enregistrer quelque chose et masquer cette logique dans une méthode MyLogger. Il y a des frais généraux pour ouvrir et fermer un fichier tout le temps, mais cette surcharge est probablement sans conséquence, sauf si vous consignez chaque itération dans une boucle.

Si le monde extérieur accède directement à log_file, vous avez de plus gros problèmes que de le fermer manuellement. S'il y a déjà une grande base de code qui déconne directement avec log_file, vous pouvez le remplacer par un petit objet qui fait la séquence open/write/close nécessaire lorsque vous y écrivez.

Questions connexes