vsh@etnibsd.UUCP (Steve Harris) (03/27/90)
I finally got around to upgrading to patch level 15 (from level 2) and,
while running the test suite, discovered an interesting problem:
in the test "op.stat", there is code that basically does:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
chdir '/usr/bin';
while (<*>) {
# increment some counters, etc.
}
# if (counter not incremented) { print error message; }
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
which kept failing on my system. I inserted a couple print statements
and discovered the main loop was not being entered! It looked like
file name globbing was broken! A few more tests showed this failure
happened in the /usr/bin directory only.
Well, to make a long story short, there existed a file in /usr/bin
named 0. That's right, the single digit zero. So it seems that the
first time into the loop, the while test failed, i.e., the value
returned by <*> was being interpreted as a numeric, not a string
value!
Now, regardless of the fact that a file named 0 probably does not
belong in /usr/bin, is this the way the <*> construct should work???
--
Steve Harris - Eaton Corp. - Beverly, MA - uunet!etnibsd!vsh
tneff@bfmny0.UU.NET (Tom Neff) (03/28/90)
In article <1121@etnibsd.UUCP> vsh@etnibsd.UUCP (Steve Harris) writes: >while (<*>) { ... >Well, to make a long story short, there existed a file in /usr/bin >named 0. That's right, the single digit zero... This problem is cool and crazy on several *levels* of cool and crazy. It gets my vote for Best Perl Weirdness Of The Week. :-) now, back to rewriting login in Perl... -- "We plan absentee ownership. I'll stick to `o' Tom Neff building ships." -- George Steinbrenner, 1973 o"o tneff@bfmny0.UU.NET
flee@shire.cs.psu.edu (Felix Lee) (03/29/90)
Perl is kinda dangerous in many ways.
I once wanted to parse multiple '-e expr' and '-f file' options the
way 'sed' does, with or without a space between the option and the
argument. Without much thought, I wrote the following, which handles
the optional space in a single statement:
while ($_ = shift) {
&expression($1 || shift), next if (/^-e(.*)$/);
&file($1 || shift), next if (/^-f(.*)$/);
# ...
}
Unfortunately, this doesn't work properly for '-e0', '-f0', or '0'.
If strings weren't converted to numbers in boolean contexts . . .
--
Felix Lee flee@shire.cs.psu.edu *!psuvax1!flee
merlyn@iwarp.intel.com (Randal Schwartz) (03/29/90)
In article <Etr4*$3@cs.psu.edu>, flee@shire (Felix Lee) writes: | Perl is kinda dangerous in many ways. s/kinda //; # :-) | I once wanted to parse multiple '-e expr' and '-f file' options the | way 'sed' does, with or without a space between the option and the | argument. Without much thought, I wrote the following, which handles | the optional space in a single statement: | while ($_ = shift) { | &expression($1 || shift), next if (/^-e(.*)$/); | &file($1 || shift), next if (/^-f(.*)$/); | # ... | } | Unfortunately, this doesn't work properly for '-e0', '-f0', or '0'. | | If strings weren't converted to numbers in boolean contexts . . . while ($_ = shift) { &expression(length ? $_ : shift), next if s/^-e//; &file(length ? $_ : shift), next if s/^-f//; # ... } I just came up with this while replying. Lemme know if you like it. I like it so far... it looks pretty clean and direct. $_ = "Just a sed user,";s/a/another/;s/sed/Perl/;s/user/hacker/;print -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
merlyn@iwarp.intel.com (Randal Schwartz) (03/29/90)
In article <1990Mar28.180657.22785@iwarp.intel.com>, merlyn@iwarp (Randal Schwartz) writes: | while ($_ = shift) { | &expression(length ? $_ : shift), next if s/^-e//; | &file(length ? $_ : shift), next if s/^-f//; | # ... | | } | | I just came up with this while replying. Lemme know if you like it. | I like it so far... it looks pretty clean and direct. But of course, after testing it (*after* posting it, sigh... :-), I find that I must put parens around length, as in (length), or make it length($_). Sigh. Overloading of the '?' operator bit me again. Sorry for the first posting being incorrect. (And I'm supposed to have this syntax *mastered* by now? :-) I did come up with an additional widget that you might find interesting: @ARGV = ("-eE1","-e","E2","-fF1","-f","F2"); ## for demo purposes sub handle_e { print "e: @_\n"; } sub handle_f { print "f: @_\n"; } while ($_ = shift) { $sub="handle_$1", do $sub ((length)?$_:shift), next if s/^-([ef])//; unshift(@ARGV,$_), last; } Try that. (I actually did, this time... :-) $_="reJ alounPt srhaetchr, ek";s/(..)(.)(..)/(print$2),$3.$1/eg;s/(.)(.)(.)/(print$2),$3.$1/eg;print -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
flee@shire.cs.psu.edu (Felix Lee) (03/29/90)
Randal L. Schwartz <merlyn@iwarp.intel.com> wrote: > while ($_ = shift) { > &expression(length ? $_ : shift), next if s/^-e//; > &file(length ? $_ : shift), next if s/^-f//; > # ... > } Okay. That looks pretty usable, if still somewhat frightening. I'll have to remember to use "length" rather than testing strings directly. Note, the while loop should read: while (length($_ = shift)) to handle "0" arguments properly... -- Felix Lee flee@shire.cs.psu.edu *!psuvax1!flee
merlyn@iwarp.intel.com (Randal Schwartz) (03/29/90)
In article <E-hyh#3@cs.psu.edu>, flee@shire (Felix Lee) writes: | Randal L. Schwartz <merlyn@iwarp.intel.com> wrote: | > while ($_ = shift) { | > &expression(length ? $_ : shift), next if s/^-e//; | > &file(length ? $_ : shift), next if s/^-f//; | > # ... | > } | | Okay. That looks pretty usable, if still somewhat frightening. I'll | have to remember to use "length" rather than testing strings directly. | Note, the while loop should read: | while (length($_ = shift)) | to handle "0" arguments properly... [See my other posting for a bug fix to the included code.] The while loop should read instead: while (@ARGV) { $_ = shift; ... ... } to handle zero-length arguments, if you're gonna get picky. :-) ($_="Just another Perl hacker,"); 0 while s#.# do {print $&;} #e,s/^1//; -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
flee@shire.cs.psu.edu (Felix Lee) (03/29/90)
Randal Schwartz <merlyn@iwarp.intel.com> wrote: > The while loop should read instead: > while (@ARGV) { > $_ = shift; > } > to handle zero-length arguments, if you're gonna get picky. :-) Urf. I'm too used to Icon's notion of success and failure, and I seem to try to apply it to perl all the time, probably because perl has a conciseness vaguely reminiscent of Icon. I should back off and try not to pack things so tightly. undef$/.open($_='>TcUENMaQ$RraE9wDKkh',$0).grep(print(substr($_, (ord)-32, 1)),split(/c\s/,join(<$_>."c\t",split(//)))) -- Felix Lee flee@shire.cs.psu.edu *!psuvax1!flee