Ruby File.open et le besoin de f.close

Il est de notoriété publique dans la plupart des langages de programmation que le stream de travail avec les fichiers est open-use-close. Pourtant, j’ai vu à plusieurs resockets dans les codes ruby ​​des appels File.open inégalés, et d’ailleurs j’ai trouvé ce joyau de connaissance dans les ruby ​​docs:

Les stream d’E / S sont automatiquement fermés lorsqu’ils sont réclamés par le récupérateur de place.

darkredandyellow amical irc prendre sur la question:
[17:12] oui, et le nombre de descripteurs de fichiers est généralement limité par le système d’exploitation
[17:29] Je suppose que vous pouvez facilement manquer de descripteurs de fichiers disponibles avant que le ramasse-miettes ne nettoie. dans ce cas, vous pourriez vouloir les utiliser vous-même. “réclamé par le ramasse-miettes.” signifie que le GC agit à un moment donné dans le futur. et c’est cher. beaucoup de raisons de fermer explicitement les fichiers.

  1. Avons-nous besoin de fermer explicitement
  2. Si oui, pourquoi le CPG est-il autoclavé?
  3. Sinon, pourquoi l’option?

J’ai vu plusieurs fois dans les codes ruby ​​des appels File.open inégalés

Pouvez-vous donner un exemple? Je ne vois jamais que dans le code écrit par les débutants qui n’ont pas “la connaissance commune dans la plupart des langages de programmation que le stream de travail avec les fichiers est ouvert à l’utilisation”.

Les Rubyists expérimentés ferment explicitement leurs fichiers ou, plus exactement, utilisent la forme de bloc de File.open , qui ferme automatiquement le fichier pour vous. Son implémentation ressemble à quelque chose comme ceci:

 def File.open(*args, &block) return open_with_block(*args, &block) if block_given? open_without_block(*args) end def File.open_without_block(*args) # do whatever ... end def File.open_with_block(*args) yield f = open_without_block(*args) ensure f.close end 

Les scripts sont un cas particulier. Les scripts s’exécutent généralement si peu et utilisent si peu de descripteurs de fichiers qu’il n’est tout simplement pas logique de les fermer, car le système d’exploitation les ferme quand même à la sortie du script.

Avons-nous besoin de fermer explicitement?

Oui.

Si oui, pourquoi le CPG est-il autoclavé?

Parce qu’après avoir collecté l’object, il n’y a plus moyen de fermer le fichier, et donc vous perdriez les descripteurs de fichiers.

Notez que ce n’est pas le garbage collector qui ferme les fichiers. Le garbage collector exécute simplement les finaliseurs pour un object avant de le récupérer. Il se trouve que la classe File définit un finaliseur qui ferme le fichier.

Sinon, pourquoi l’option?

Le gaspillage de mémoire étant bon marché, les descripteurs de fichiers gaspillés ne le sont pas. Par conséquent, cela n’a pas de sens de lier la durée de vie d’un descripteur de fichier à la durée de vie de certaines parties de la mémoire.

Vous ne pouvez simplement pas prédire quand le ramasse-miettes sera exécuté. Vous ne pouvez même pas prédire s’il s’exécutera du tout : si vous ne manquez jamais de mémoire, le ramasse-miettes ne fonctionnera jamais, donc le finaliseur ne s’exécutera jamais, par conséquent le fichier ne sera jamais fermé.