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

I am running a script that will eventually send e-mails through a senmail pipe on unix. I want to test this script, but want the messages to show up on my screen rather than sending an e-mail for each time I run it. So, specificly, I want to open STDOUT to MAILPIPE, so that when I call something like print MAILPIPE "blah blah blah"; it will print to my screen. Any thoughts? Thanks in advance, thor

Replies are listed 'Best First'.
(tye)Re: Changing the name of STDOUT...
by tye (Sage) on Feb 20, 2001 at 01:21 UTC

    I'll write this really quickly so you'll get the warning before anyone suggests that you do *MAILPIPE= *STDOUT.

    Doh! ;)

    But seriously, *MAILPIPE= *STDOUT seems to have become a common idiom, but I don't like it much (I used it once in a very special situation and even then I commented the code to say it was a "last resort" and likely still had problems).

    One problem in this particular case is that when your program gets to the close MAILPIPE, it will actually be closing STDOUT and any further output to STDOUT will be lost.

    What I suggest you use instead is:

    open( MAILPIPE, ">&STDOUT" ) or die "Can't dup STDOUT to MAILPIPE: $!\n";

            - tye (but my friends call me "Tye")
Re (tilly) 1: Changing the name of STDOUT...
by tilly (Archbishop) on Feb 20, 2001 at 01:52 UTC
    Why are you negotiating with sendmail directly? Just use Mail::Send. This will simplify your code and make it more portable.

    Then the solution to your problem is to create a "fake" version of that module which uses the same API and just echos back to the screen rather than sending mail. Change which use you do, and all of a sudden you are sending mail rather than printing.

    Failing that I would take tye's advice above.

Re: Changing the name of STDOUT...
by myocom (Deacon) on Feb 20, 2001 at 01:08 UTC

    Seems to me that you should be able to do this:

    *MAILPIPE = *STDOUT; # Point the MAILPIPE symbol to STDOUT's
    ...before your first print MAILPIPE and it should redirect to STDOUT instead.
      It's not nice to go mucking around in someone else's namespace. Further, when you alias a filehandle, your stdio library is going to get very confused when you seek, tell, close, dup and do other things to the underlying filehandle.

      Use the open(MAILPIPE, ">&STDOUT") or die idiom instead.

      That did the trick! Thanx
Re: Changing the name of STDOUT...
by chromatic (Archbishop) on Feb 21, 2001 at 00:14 UTC
    In the spirit of multiple ways to do things, add a simple function that uses select to choose a default output filehandle.

    Inside that function, check for a $debug flag. If set, select STDOUT. Otherwise, select MAILPIPE.

    You'll probably want to select STDOUT again after you're done, so you might have a generic printing method that combines the options.

    Barring that, I'd recommend tilly's solution of a debugging module written to the same API. Why dup a filehandle when there are other options available that use less typing?

(jptxs) Re: Changing the name of STDOUT...
by jptxs (Curate) on Feb 20, 2001 at 01:05 UTC
    maybe it's just me, but, rather than go for the complexity for the sake of testing, I always just do something stupid like use regular print's until i get the results I want and add the MAILPIPE stuff later. Why build a jet when all you need is a car?
    "A man's maturity -- consists in having found again the seriousness one had as a child, at play." --Nietzsche
      Normally, I would as well. Except that when I first started the project, I knew that there would be a LOT of them. I figured that it would be easier to write them all in from the start, and then just change one line, rather than many. thor
        yeah, I guess *MAILPIPE = *STDOUT is easy enough to do. I just get off on global replaces in vi, I guess =)
        "A man's maturity -- consists in having found again the seriousness one had as a child, at play." --Nietzsche
Re: Changing the name of STDOUT...
by a (Friar) on Feb 20, 2001 at 10:44 UTC
    Well, your talk of complexity later on included; build it w/ the debug in and a non-mailing mode:
    print MAILPIPE 'blah $blah' if $mailing; print STDERR "trying MAILPIPE 'blah $blah'\n" if $debug > 30;
    so you can $mailing = 0; $debug =40; and get stderr and no mail. Just keep your debug in line w/ your MAILPIPE data as the code evolves.

    a