Ho visto molte volte File.open
chiamate senza corrispondenza nei codici Ruby
Puoi fare un esempio? Vedo solo che nel codice scritto da principianti a cui manca la "conoscenza comune nella maggior parte dei linguaggi di programmazione che il flusso per lavorare con i file è aperto-usa-chiudi".
Gli esperti Rubyists chiudono esplicitamente i loro file o, più idiomaticamente, usano la forma di blocco di File.open
, che chiude automaticamente il file per te. La sua implementazione è fondamentalmente simile a questa:
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
Gli script sono un caso speciale. Gli script generalmente sono così brevi e usano così pochi descrittori di file che semplicemente non ha senso chiuderli, poiché il sistema operativo li chiuderà comunque quando lo script esce.
Dobbiamo chiudere esplicitamente?
Sì.
Se sì, perché il GC si chiude automaticamente?
Perché dopo che ha raccolto l'oggetto, non è più possibile chiudere il file e quindi si perdono i descrittori dei file.
Nota che non è il garbage collector che chiude i file. Il garbage collector esegue semplicemente qualsiasi finalizzatore per un oggetto prima che lo raccolga. Accade così che la File
classe definisca un finalizzatore che chiude il file.
In caso contrario, perché l'opzione?
Perché la memoria sprecata costa poco, ma i descrittori di file sprecati no. Pertanto, non ha senso legare la durata di un descrittore di file alla durata di qualche pezzo di memoria.
Semplicemente non è possibile prevedere quando verrà eseguito il Garbage Collector. Non si può nemmeno prevedere se verrà eseguito a tutti : se mai a corto di memoria, il garbage collector non potrà mai funzionare, quindi il finalizzatore verrà mai eseguito, quindi il file non verrà mai chiusa.