如何在Perl中自动释放RAII风格的资源?
发布时间:2020-12-15 23:24:54 所属栏目:大数据 来源:网络整理
导读:假设我有一个必须释放的资源(例如文件句柄或网络套接字): 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: $!"; 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/perl use 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 properlyn"; } ); process($fh); } sub process { die "cannot processn" } 但是,正如@Philip在注释中所指出的那样,Scope :: Guard使用DESTROY方法,该方法会在运行范围退出代码时产生一些不确定性. Hook :: Scope和Sub :: ScopeFinalizer等模块看起来也很好,尽管我从未使用它们. 我喜欢Try::Tiny的干净界面和纯粹的简洁性,它将帮助您以正确的方式处理异常: #!/usr/bin/perl use 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 properlyn"; }; sub process { die "cannot processn" } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |