# -*- mode: perl; coding: utf-8 -*- package YATT::Util::Finalizer; use strict; use warnings FATAL => qw(all); use base qw(Exporter); BEGIN { our @EXPORT = qw(with_select capture finally); our @EXPORT_OK = @EXPORT; } sub new { my ($pack, $code) = splice @_, 0, 2; bless [$code, @_], $pack; } sub finally (&@) { __PACKAGE__->new(@_); } sub DESTROY { my $self = shift; if ($@) { # XXX: This can be hard to catch. syswrite STDOUT, "\n\n[$@]" if $ENV{DEBUG_ERROR}; } my $code = $self->[0] or return; $code->(@$self[1 .. $#$self]); } sub cancel { undef shift->[0]; } sub with_select { # newfh, body, [strref] my $strref; unless (defined $_[0]) { $strref = $_[2] || do {my $str = ""; \$str}; open $_[0], '>', $strref or die "Can't open strref: $!"; } my $finalizer = finally { select($_[0]); } select; select($_[0]); $_[1]->($finalizer); defined $strref && $$strref; } sub capture (&@) { with_select my ($fh), $_[0]; } 1;