neilwatson has asked for the wisdom of the Perl Monks concerning the following question:

Greetings,

Consider this code. When I run it, and there is an error, I never see the output from warn. Why is that, can I fix it, or am I doing it wrong?

#!/usr/bin/perl use strict; use warnings; use Test::Simple tests => 1; sub mycheck { open( FH, '>', '/tmp/x/logfile' ) or return sub { warn "Cannot open file [$!]"; return 1; }; foreach my $line (<DATA>) { print FH $line or return sub { warn "Cannot write to file [$!]"; return 2; }; } close FH; return 0 } ok( mycheck() == 0, "mycheck test" ); __DATA__ dr_test_class ;; empty ;; empty ;; empty ;; empty dr_test_kept ;; handle_dr_test ;; /etc/dr_test ;; ;; kept ;; mojolicio +us $ ./foo.pl 1..1 not ok 1 - mycheck test # Failed test 'mycheck test' # at ./foo.pl line 26. # Looks like you failed 1 test of 1.

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Getting stderr from a test::simple
by AppleFritter (Vicar) on Jul 01, 2014 at 18:05 UTC
    Why do you expect this to print a warning? If the open call in mycheck fails, you return an anonymous subroutine. Test::Simple checks if this equals 0 (which it does not), so the test fails. At no point is the subroutine you return actually called, hence no warning.

        Acceptable, probably, but if you merely want to print a warning in addition to making the test fail, I'd say do is your best choice:

        open (FH, '>', '/tmp/x/logfile') or do { warn "Cannot open file [$!]"; return 1; };

        There may well be more idiomatic ways of doing (no pun intended) this that I'm not aware of. My monastic brothers will (probably) be happy to chime in!

Re: Getting stderr from a test::simple
by Laurent_R (Canon) on Jul 01, 2014 at 18:01 UTC
    Returning a reference to an anonymous subroutine does not mean that this subroutine will be executed.
Re: Getting stderr from a test::simple
by jeffa (Bishop) on Jul 02, 2014 at 14:42 UTC

    Why are you returning sub refs? Try this instead:

    use strict; use warnings; use Test::More tests => 1; sub mycheck { open( FH, '>', '/tmp/x/logfile' ) or return 1; foreach my $line (<DATA>) { print FH $line or return 2; } close FH; return 0 } my $return = mycheck(); is $return, 0, "got expected return value: $return"; __DATA__ dr_test_class ;; empty ;; empty ;; empty ;; empty dr_test_kept ;; handle_dr_test ;; /etc/dr_test ;; ;; kept ;; mojolicio +us

    Ahhhh, much better! :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)