Here is a little project I'd like a bit of feedback on.
Not to long ago Anony put up this node. It was a little frusterating to watch. Not only was the mistake a common, simple one, but little niggles of system got even BrowserUK. And frankly, who hasn't been bit by it, once or twice, early in their Perl career?
Another niggle is Perl's error vars. Which one to use, when? And, though system calls are rarely portable, almost no one ever remembers to mention $^E on the off chance that the asker is on a VMS, Win32, or OS/2 system.
Both these issues are tidied up in Perl 6. But who wants to wait that long?
So, Shell::DWIM is intended to clean up these little niggles in a consistent way. I hope that it gets itself established enough that we can all point to it whenever a similar question comes down the pipeline. First, a little documentation, as none is currently supplied.
Shell::DWIM currently has no export system, in order to keep things simple for me. It provides two features.
- Shell::DWIM::run - This function is a RWIM (return what I mean) replacement for system. It returns true for a succesful execution, false for a failure. It does not support system's indirect object features currently. Unlike system it captures the exception generated by passing it tainted data, and sets $Shell::DWIM::RUN_ERROR appropriately.
- $Shell::DWIM::RUN_ERROR - This special variable is set by calls to Shell::DWIM::run. It attempts to be whichever of the four Perl error variables you need, with a few caveats. First, it does not have the number/string magic of $! - it is always stringified. Second, it prefers extended OS errors to the C errno on systems that have extended error support (currently VMS, OS/2, and Win32).
Suggested use:
Shell::DWIM::run $shell_commands or die $Shell::DWIM::RUN_ERROR;
What I ask of the Monastery is a code review and comment. Here are my specific concerns (there are several):
- run and $RUN_ERROR are terrible names - anyone have better ideas?
- Currently run traps the exception caused by system $tainted_data. Should it?
- On the same note, it localizes $@ anticipating that no one will expect the eval{} that run uses internally. Since the other error vars are set correctly, is this application of the Principle of Least Surprise a bit too waterbed like?
- While there is little that goes on that might be suspect, there is a bit of code between system @_ and the use of $! and $^E (called $OS_ERROR internally). perlvar warns that $! should be used immediatly. Is there a danger there?
- If $^E is supported, we use it instead of $!. Is this gonna bite anyone in the butt?
- With a little case specific aliasing, $RUN_ERROR could be made to support $! special magic. But then it could be reset by things other than calls to run. What's your opinion?
- And finally, How's My Hacking? I'm a bit of a hobbyist programmer, so my style hasn't really gelled yet. Is there anything grossly stupid in the code?
Speaking of which:
Cheers,package Shell::DWIM; use warnings; use strict; our ($EVAL_ERROR, $CHILD_ERROR, $OS_ERROR, $RUN_ERROR); #Setup internal friendly error names *EVAL_ERROR = \$@; *CHILD_ERROR = \$?; if ($^O =~ /VMS|MSWin|OS\/2/) { #These systems support an extended OS +error message ($^E) *OS_ERROR = \$^E; #$OS_ERROR reflects that value if it e +xists. This clashes somwhat with English.pm } else { *OS_ERROR = \$!; } #The public function sub run { my ($return) = 0; local $EVAL_ERROR; #The eval here is a little unexpected, so we lo +calize $EVAL_ERROR so no one get's bitten eval { $return = (( system @_ ) == 0); }; if ($return) { $RUN_ERROR = undef; } else { SWITCH: { do { $RUN_ERROR = $EVAL_ERROR && last SWITCH } if $EVAL_E +RROR ; do { $RUN_ERROR = $CHILD_ERROR && last SWITCH } if $CHILD_ +ERROR > 0 ; do { $RUN_ERROR = "$OS_ERROR" && last SWITCH } if $CHILD_ +ERROR == -1; #String version of $OS_ERROR LAST_CASE: { $RUN_ERROR = "Exception, package CommandLine: system() fai +led, error unknown"} } } return $return; } 1; #Because you gotta
Erik
Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: RFC: Shell::DWIM
by grinder (Bishop) on Oct 07, 2002 at 08:01 UTC | |
by erikharrison (Deacon) on Oct 07, 2002 at 14:09 UTC | |
Re: RFC: Shell::DWIM
by Zaxo (Archbishop) on Oct 07, 2002 at 16:52 UTC | |
by erikharrison (Deacon) on Oct 07, 2002 at 17:21 UTC | |
Re: RFC: Shell::DWIM
by Aristotle (Chancellor) on Oct 09, 2002 at 20:48 UTC |