Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Testing failures: How to override print to make it fail?

by eyepopslikeamosquito (Archbishop)
on May 05, 2005 at 03:00 UTC ( [id://454223]=perlquestion: print w/replies, xml ) Need Help??

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

I want to test open and print failures. This crude trick overrides open with a failing one:

BEGIN { *CORE::GLOBAL::open = sub (*;$$) { return undef }; } open(my $fh, '>', 'f.tmp') or die "error: open"; print $fh "hello\n" or die "error: print";
However, this attempt does not override print with a failing one:
BEGIN { *CORE::GLOBAL::print = sub (*;@) { return undef }; } open(my $fh, '>', 'f.tmp') or die "error: open"; print $fh "hello\n" or die "error: print";
I suspect I just need to get the right prototype for print. How do I override the print function to make it fail?

Replies are listed 'Best First'.
Re: Testing failures: How to override print to make it fail?
by blokhead (Monsignor) on May 05, 2005 at 03:43 UTC
    You can force print to fail by selecting a filehandle that you know is unwritable. Here's a quick-n-dirty little module that returns a tied filehandle that fails when written to:
    package NoPrint; use Symbol; sub new { my $sym = gensym; tie *$sym, $_[0]; bless $sym, $_[0]; } sub TIEHANDLE { bless {}, $_[0] } sub PRINT { return undef } sub PRINTF { return undef } sub WRITE { return undef }
    You can now use it like this:
    my $old_fh = select NoPrint->new; ## deep inside some test somewhere... print "foo\n" or warn "print failed (1)"; select $old_fh; ## now printing is back to normal again: print "foo\n" or warn "print failed (2)";
    Update: An alternative that might even be is much cleaner is to localize *STDOUT:
    { local *STDOUT = NoPrint->new; print "foo\n" or warn "print failed (1)"; } print "foo\n" or warn "print failed (2)";

    blokhead

Re: Testing failures: How to override print to make it fail?
by tlm (Prior) on May 05, 2005 at 03:13 UTC
Re: Testing failures: How to override print to make it fail?
by adrianh (Chancellor) on May 05, 2005 at 10:12 UTC
    How do I override the print function to make it fail?

    Another alternative to the others offered is to encapsulate the dying-print in a subroutine and then override that. I like this solution myself since it saves sprinkling "or die" everywhere.

Re: Testing failures: How to override print to make it fail?
by dragonchild (Archbishop) on May 05, 2005 at 13:18 UTC
    What scenario are you envisioning that a print failing will be the sole indicator of a failure state?

    • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
    • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
      What scenario are you envisioning that a print failing will be the sole indicator of a failure state?

      You can have a print fail due to, for example, lack of space on the device and then have the close succeed later on.

      There's also the argument that it's better to FailFast.

        If you're printing to a filehandle, then use a IO::File-derived class that will encapsulate that die for you, and test that. I'm not quite sure how STDOUT or STDERR runs out of space, though.

        • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
        • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

      I'm helping a workmate write his first ever tests for a new function he added to an existing module. Seeing that his new function had:

      open ... or die ... print ... or die ...
      I suggested it is good form to write tests for exceptional conditions ... then realized I had no idea how to do it. :-) BTW, Devel::Cover also nags you if you don't test the or die branches.

        print() is generally considered one of those functions that "Just Works". adding "or die" to print is kinda ... dumb.

        Of course, if you absolutely had to test print's success or failure, you could

        use Fatal qw( print );

        As for Devel::Cover ... I shoot for 90%+ coverage. There are several good conversations on D::C and why attempting to achieve 100% is ... well ... dumb. :-)


        • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
        • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://454223]
Approved by tlm
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-03-29 01:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found