Closed KES777 closed 9 years ago
Capture::Tiny is designed to capture. Exception handling is an orthogonal concern that won't be included. You can already include any exception handling you want inside the capture block:
my ( $stdout, $stderr, $result ) = capture { eval { print "YES"; die; 1; } };
You do not understand. I do not ask to do exception handling. I ask to change format of calling. This change allow 'capture' even in case when code is died. I also do not want extra exception handling and rethrowing it in my code.
Let compare: my ( $result ) = capture { print "YES"; die; 1; }, my( $stdout, $stderr );
VS
use Try::Tiny; my $saved_error; my ( $stdout, $stderr, $result ) = capture { try { print "YES"; die; 1; } catch { $savederror = $; undef; } }; die $saved_error if $saved_error;
Second is crazy code in compare with first.
Also in case I sugeest to you. Module API is going to be more clear. Just one method VS three
Certainly, at this point the API will not change.
In your second code example, the try/catch are pointless, as $saved_error
is the same error that would be thrown if you didn't use try/catch in the first place and you're not doing anything with $stdout
, $stderr
, or $result
anyway.
I don't understand what you think would be different with capture variables passed as arguments.
I don't understand what you think would be different with capture variables passed as arguments.
#!/usr/bin/perl
sub capture1 {
my $result = 1;
$stdout = 'Some text printed to stdout';
die 'Enexpected exception';
return ( $stdout, $stderr, $result );
}
sub capture2 {
my $result = 1;
my $stdout = \$_[1];
$$stdout = 'Some text printed to stdout';
die 'Enexpected exception';
return ( $stdout, $stderr, $result );
}
my( $stdout, $stderr, $result );
eval {
# we need force scalar
($stdout, $stderr, $result) = capture1( scalar sub{ } );
};
print "EXAMPLE 1: $stdout, $stderr, $result\n";
eval {
# scalar context by nature
$result = capture2( sub{ }, $stdout, $stderr );
};
print "EXAMPLE 2: $stdout, $stderr, $result\n";
program OUTPUT is:
EXAMPLE 1: , ,
EXAMPLE 2: Some text printed to stdout, ,
See difference? =)
Certainly, at this point the API will not change.
I ask to extend API. Your capture_* you can leave forever or maybe in far future start long deprecation period.
In your second code example, the try/catch are pointless
Of course I want to do something with $stdout. And I will do. As I showed before in example 'capture1' In case of your API it is impossible to handle exception and catch $stdout.
This is more sensitive in web based applications where I need to know and analize what is already sent to STDOUT before exception occour.
It's not documented, but $@
is preserved (as is $?
). So you can just do this:
my ($stdout, $stderr, $result) = capture { eval { print "some text"; die "fatal" } };
my $err = $@;
# $stdout contains "some text"
# $err contans "fatal at ..."
How is that?
Allow capturing when &code
This will never catch "YES" my ( $stdout, $stderr, $result ) = capture { print "YES"; die; 1; };
Allow structure like:
my ( $stdout, $stderr ); my $result = capture { print "YES"; die; } $stdout, $stderr; So I always have captured $stdout and $stderr
Also this allow to kill useless capture_* because of: my $result = capture { print "YES"; die; } $stdout; my $result = capture { print "YES"; die; } undef, $stderr; my $result = capture { print "YES"; die; } $merged, $merged;
About $merged: inside 'capture' you can check that $stdout == $stderr so it is $merged