J'ai vu plusieurs fois dans les codes rubis des File.open
appels inégalés
Pouvez-vous donner un exemple? Je ne vois jamais que dans le code écrit par des débutants qui n'ont pas la "connaissance commune de la plupart des langages de programmation que le flux pour travailler avec des fichiers est open-use-close".
Les rubisistes expérimentés ferment explicitement leurs fichiers ou, plus idiomatiquement, utilisent la forme de bloc de File.open
, qui ferme automatiquement le fichier pour vous. Son implémentation ressemble essentiellement à 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 sont généralement si courts et utilisent si peu de descripteurs de fichiers qu'il n'a tout simplement pas de sens de les fermer, car le système d'exploitation les fermera de toute façon lorsque le script se terminera.
Avons-nous besoin de fermer explicitement?
Oui.
Si oui, pourquoi le GC se ferme-t-il automatiquement?
Parce qu'après avoir collecté l'objet, il n'y a plus moyen pour vous de fermer le fichier, et ainsi vous fuiriez des descripteurs de fichier.
Notez que ce n'est pas le garbage collector qui ferme les fichiers. Le garbage collector exécute simplement tous les finaliseurs pour un objet avant de le collecter. Il se trouve que la File
classe définit un finaliseur qui ferme le fichier.
Si non, pourquoi l'option?
Parce que la mémoire gaspillée est bon marché, mais pas les descripteurs de fichiers gaspillés. Par conséquent, il n'est pas logique de lier la durée de vie d'un descripteur de fichier à la durée de vie d'un morceau de mémoire.
Vous ne pouvez tout simplement pas prédire quand le garbage collector s'exécutera. Vous ne pouvez même pas prédire s'il fonctionnera du tout : si vous ne manquez jamais de mémoire, le garbage collector ne fonctionnera jamais, donc le finaliseur ne fonctionnera jamais, donc le fichier ne sera jamais fermé.