Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Getting the Behavior of the "file open or die" Pragma but with a Program Pause

by perldigious (Priest)
on Oct 10, 2016 at 15:31 UTC ( #1173661=perlquestion: print w/replies, xml ) Need Help??

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

Hello fellow Monasterians,

I'm asking for opinions on possibly better ways to do the following.

open(my $Raw_fh, ">", "Output_Raw.txt") or file_open_error_abort("Outp +ut_Raw.txt"); # This subroutine will print a file open error message, including the +filename passed to it, and terminate the program after an acknowledge +ment from the user. sub file_open_error_abort { my $filename = $_[0]; say "Cannot open \"$filename\": $!."; print "---Press Enter to quit---"; my $pause = <STDIN>; exit; }

I'm really just forcing the script to pause so that the user can see the error message. When I just used the standard file open() or die pragma I would get frequent calls from people attempting to manually run scripts I'd written saying they weren't working (because the window would just close immediately), and the vast majority of the time it would simply be because they had an output file open in another program therefore denying permission for the script to write to it. The my $pause = <STDIN>; pause so they can read the message largely fixed this annoyance for me, but every time I use it I cringe a little and wonder if there isn't a better, perhaps more perlish way of doing this.

UPDATE BELOW:

Thanks davido and tye, I'm going to take parts of both of your suggestions and go with the following.

use utf8; use 5.022; use strict; say "BEGIN"; open(my $out_fh, ">", "permission_denied_output_file.txt") or die "Can +not open \"permission_denied_output_file.txt\": $!."; open(my $in_fh, "<", "no_such_input_file.txt") or die "Cannot open \"n +o_such_input_file.txt\": $!."; say "END"; END { use ExtUtils::MakeMaker qw(prompt); # placing this use statement h +ere for convenient copy-paste of this END block code to other scripts +. prompt('Please hit enter to exit.') if ($?); # stop and prompt for + acknowledgement if program exits with a non-zero value. }

This code doesn't give me the same cringe as my kludge function did. I tested it with an .exe generated via PAR::PACKER and it works as expected for the two cases above (on my machine anyway) and doesn't cause any pause if there are no file open dies.

Much appreciated, as always.

I love it when things get difficult; after all, difficult pays the mortgage. - Dr. Keith Whites
I hate it when things get difficult, so I'll just sell my house and rent cheap instead. - perldigious

Replies are listed 'Best First'.
Re: Getting the Behavior of the "file open or die" Pragma but with a Program Pause
by davido (Cardinal) on Oct 10, 2016 at 16:17 UTC

    This is a global problem -- not just specific to the "open or die" situation you mentioned in your post. If you wish to solve it in a way that makes any calls to die result in a wait period, you may consider overriding CORE::GLOBAL::die. In this case, you would probably want to inject your wait for enter logic into CORE::GLOBAL::die, after dumping $@ to STDERR, and then exit with a non-zero exit status. brian_d_foy has a nice writeup on overriding CORE::GLOBAL::die.

    Additionally, if the "print and wait for diamond operator" idiom feels too clunky, you could:

    require ExtUtils::MakeMaker; ExtUtils::MakeMaker::prompt('Please hit enter to exit.', '');

    ...which encapsulates the ugliness in prompt, from the core module ExtUtils::MakeMaker. The advantage to using prompt is that it also quietly accepts the "default" (ie, doesn't block) if the script is run in a non-TTY environment.


    Dave

      Thanks davido, that's a wealth of information and suggestions. I even think I understand everything in the brian_d_foy writeup, at least until the last bit regarding objects. I've never diddled with the perl iternals, but what he describes doesn't seem overly complicated.

      I may fiddle a bit and try some things as you suggested (I've never tried prompt either), and then decide if I want to change from my current subroutine kludge. Thanks again.

      I love it when things get difficult; after all, difficult pays the mortgage. - Dr. Keith Whites
      I hate it when things get difficult, so I'll just sell my house and rent cheap instead. - perldigious
Re: Getting the Behavior of the "file open or die" Pragma but with a Program Pause (-Mouse)
by tye (Sage) on Oct 10, 2016 at 20:44 UTC

      I love the monastery. Yes tye, that was actually the first place my brain went when I read the brian_d_foy write up that davido linked to. By that I mean trying to figure out a way to use the END block to pause, but only in the event of a die or exit and not if the script finishes and terminates normally. I figured I would try to find a way to make that happen if I could.

      It's also pretty cool that you have a way of sneaking that in as the default behavior for all *.pl files run on a machine, and I probably would have done exactly that as well, except that 99% of the time my scripts are being run locally on various individual work PCs after I've used pp (PAR::PACKER) to compile them in to *.exe files. The * portion is included on a program "white list" maintained by my company's system administrators so all the machines connected to our network let them run around the common security lockouts (of which even cmd.exe is one, sheesh).

      I did manage to get them to add a version of Strawberry Perl to our list of corporate wide available optional software installs, but I don't like asking every new user to go out and install that, so I tend to stick with the PAR::PACKER *.exe method. I'm far from an IT guru, and having to dance the network security circumvention mamba usually just results in me being tired, frustrated, and feeling beaten down by the corporate world.

      I love it when things get difficult; after all, difficult pays the mortgage. - Dr. Keith Whites
      I hate it when things get difficult, so I'll just sell my house and rent cheap instead. - perldigious
        By that I mean trying to figure out a way to use the END block to pause, but only in the event of a die or exit and not if the script finishes and terminates normally.

        perlmod notes:

        Inside an END code block, $? contains the value that the program is going to pass to exit().

        - tye        

Re: Getting the Behavior of the "file open or die" Pragma but with a Program Pause
by stevieb (Canon) on Oct 10, 2016 at 16:02 UTC

    If you don't like having to have the user take action, you could always just do something like sleep 5;. That'll display the error for five seconds, then exit.

      I don't mind the user interaction, in fact I prefer it because it all but forces them to look at the error message. My main cringe is that I took something as clean and tidy as the one line "open or die" and use this kludge just to get the program pause behavior. I'm picking nits I'm sure, but I was hoping there was a way to keep that one line cleanliness (with the post-fix notation), get the pause, and not have to resort to a subroutine call as I do. I'm probably asking to have my cake and eat it too. :-)

      I love it when things get difficult; after all, difficult pays the mortgage. - Dr. Keith Whites
      I hate it when things get difficult, so I'll just sell my house and rent cheap instead. - perldigious

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (13)
As of 2022-12-02 16:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?