Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can not catch STDOUT, STDERR when \&code died #34

Closed
KES777 opened this issue May 26, 2015 · 5 comments
Closed

can not catch STDOUT, STDERR when \&code died #34

KES777 opened this issue May 26, 2015 · 5 comments

Comments

@KES777
Copy link

KES777 commented May 26, 2015

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

@dagolden
Copy link
Collaborator

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; } };

@KES777
Copy link
Author

KES777 commented May 27, 2015

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 { $saved_error = $_; 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

@dagolden
Copy link
Collaborator

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.

@KES777
Copy link
Author

KES777 commented May 28, 2015

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.

@dagolden
Copy link
Collaborator

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant