Que bom que você postou isso como uma pergunta. :)
Eu estava tentando dizer que destruidores e finally
são conceitualmente diferentes:
- Destrutores são para liberar recursos ( dados )
finally
é para retornar ao chamador ( controle )
Considere, digamos, este pseudocódigo hipotético:
try {
bar();
} finally {
logfile.print("bar has exited...");
}
finally
aqui está resolvendo inteiramente um problema de controle e não um problema de gerenciamento de recursos.
Não faria sentido fazer isso em um destruidor por vários motivos:
- Não coisa está sendo "adquirido" ou "criado"
- A falha na impressão no arquivo de log não resultará em vazamentos de recursos, corrupção de dados etc. (supondo que o arquivo de log aqui não seja retornado ao programa em outro local)
- É legítimo
logfile.print
fracassar, enquanto a destruição (conceitualmente) não pode fracassar
Aqui está outro exemplo, desta vez como em Javascript:
var mo_document = document, mo;
function observe(mutations) {
mo.disconnect(); // stop observing changes to prevent re-entrance
try {
/* modify stuff */
} finally {
mo.observe(mo_document); // continue observing (conceptually, this can fail)
}
}
mo = new MutationObserver(observe);
return observe();
No exemplo acima, novamente, não há recursos a serem liberados.
De fato, o finally
bloco está adquirindo recursos internamente para atingir seu objetivo, o que poderia falhar potencialmente. Portanto, não faz sentido usar um destruidor (se o Javascript tiver um).
Por outro lado, neste exemplo:
b = get_data();
try {
a.write(b);
} finally {
free(b);
}
finally
está destruindo um recurso b
,. É um problema de dados. O problema não é devolver o controle corretamente ao chamador, mas evitar vazamentos de recursos.
Falha não é uma opção e nunca deve (conceitualmente) ocorrer.
Cada lançamento de b
é necessariamente associado a uma aquisição e faz sentido usar o RAII.
Em outras palavras, apenas porque você pode usar para simular ou isso não significa que ambos são um e o mesmo problema ou que ambos são soluções apropriadas para os dois problemas.