如何在Perl中自动释放RAII风格的资源?

如何在Perl中自动释放RAII风格的资源?,第1张

概述假设我有一个必须释放资源(例如文件句柄或网络套接字): open my $fh, "<", "filename" or die "Couldn't open filename: $!";process($fh);close $fh or die "Couldn't close filename: $!"; 假设该过程可能会死亡.然后代码块提前退出,$fh不会关闭. 我可以明确检查错误: op 假设我有一个必须释放的资源(例如文件句柄或网络套接字):

open my $fh,"<","filename" or dIE "Couldn't open filename: $!";process($fh);close $fh or dIE "Couldn't close filename: $!";

假设该过程可能会死亡.然后代码块提前退出,$fh不会关闭.

我可以明确检查错误:

open my $fh,"filename" or dIE "Couldn't open filename: $!";eval {process($fh)};my $saved_error = $@;close $fh or dIE "Couldn't close filename: $!";dIE $saved_error if $saved_error;

但是这种代码很难做到正确,而且只有在添加更多资源时才会变得更加复杂.

在C中,我将使用RAII来创建一个拥有该资源的对象,并且其析构函数将释放它.这样,我不必记住释放资源,并且一旦RAII对象超出范围,资源清理就会正确发生 – 即使抛出异常.不幸的是,在Perl中,DESTROY方法不适用于此目的,因为无法保证何时调用它.

是否存在Perlish方法以确保即使在存在异常情况下资源也会自动释放?或者是显式错误检查唯一选项?

解决方法 我认为这就是 Scope::Guard旨在帮助的.

#!/usr/bin/perluse strict; use warnings;use Scope::Guard;my $filename = 'file.test';open my $fh,'>',$filename    or dIE "Couldn't open '$filename': $!";{    my $sg = Scope::Guard->new(        sub {            close $fh or dIE "Could not close";            warn "file closed properly\n";        }    );    process($fh);}sub process { dIE "cannot process\n" }

但是,正如@Philip在注释中所指出的那样,Scope :: Guard使用DESTROY方法,该方法会在运行范围退出代码时产生一些不确定性. Hook :: Scope和Sub :: ScopeFinalizer等模块看起来也很好,尽管我从未使用它们.

我喜欢Try::Tiny的干净界面和纯粹的简洁性,它将帮助您以正确的方式处理异常:

#!/usr/bin/perluse strict; use warnings;use Try::Tiny;my $filename = 'file.test';open my $fh,$filename    or dIE "Couldn't open '$filename': $!";try {    process($fh);}catch {    warn $_;}finally {    close $fh        and warn "file closed properly\n";};sub process { dIE "cannot process\n" }
总结

以上是内存溢出为你收集整理的如何在Perl中自动释放RAII风格的资源?全部内容,希望文章能够帮你解决如何在Perl中自动释放RAII风格的资源?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1265844.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存