home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / perl / 5378 < prev    next >
Encoding:
Internet Message Format  |  1992-08-18  |  2.5 KB

  1. Path: sparky!uunet!usc!news!netlabs!lwall
  2. From: lwall@netlabs.com (Larry Wall)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: Bug with $number variables ???
  5. Message-ID: <1992Aug19.065228.8707@netlabs.com>
  6. Date: 19 Aug 92 06:52:28 GMT
  7. References: <1992Aug19.040708.519@ucsu.Colorado.EDU>
  8. Sender: news@netlabs.com
  9. Organization: NetLabs, Inc.
  10. Lines: 57
  11. Nntp-Posting-Host: scalpel.netlabs.com
  12.  
  13. In article <1992Aug19.040708.519@ucsu.Colorado.EDU> farnham@spot.Colorado.EDU (Farnham Dave) writes:
  14. : The two lines I'm referring to are:
  15. :     ($login = $1) =~ s/:$//;  # remove ':'
  16. :     $shell = $2;
  17. : In PL-35 "$2" has vanished.  It appears that after a
  18. : substitute all the $number variables get reset to null
  19. : even if I don't do another capture.
  20. : This wasn't the case in PL-19.  Was I abusing PL-19 or
  21. : did something break?
  22.  
  23. It's documented that $1 et al refer back to the last successful pattern
  24. match (which includes patterns used by substitutes).  It was more or
  25. less a bug in 4.019 that a successful match didn't always invalidate
  26. prior values.  It's best to capture $1, $2, etc. immediately before
  27. doing another pattern match, unless you really do want $2 from the last
  28. successful match.  I'd usually do either of
  29.  
  30.     if ($line =~ /($search_str).*:.*:.*:.*:.*:(.*)$/) {
  31.     ($login, $shell) = ($1,$2);
  32.     $login =~ s/:$//;
  33.  
  34. or
  35.  
  36.     if (($login,$shell) = $line =~ /($search_str).*:.*:.*:.*:.*:(.*)$/) {
  37.     $login =~ s/:$//;
  38.  
  39. By the way, that's a VERY inefficient pattern.  Consider that each of
  40. those .*'s must go to the end of the string and then back off,
  41. recursively trying all the rest of the patterns after it, which in turn
  42. go to the end of the string, recursively trying all the rest of the
  43. patterns after it, which in turn go to the end...  You get the picture.
  44. It'd be faster to use [^:]* when you mean it.  Also, you should put an
  45. o modifier on if the pattern is fixed for a given process run.
  46.  
  47. It'd be much faster to just take advantage of the fact that .* will match
  48. everything to the last ":", like this:
  49.  
  50.     $search_str = '^farnham\b';
  51.     ...
  52.     ($login,$shell) = $line =~ /($search_str).*:(.*)$/o;
  53.  
  54. Or just throw in a
  55.  
  56.     next unless $line =~ /$search_str/o;
  57.     ($login,$pw,$uid,$gid,$gcos,$home,$shell) = split(/:/,$line);
  58.  
  59. Since you don't execute the split line very often, it doesn't matter
  60. how long it takes.  Even if you did the split on every line it'd still
  61. be faster than your original pattern.
  62.  
  63. Rule of Thumb: Never use .* when you can use something else.
  64.  
  65. Now, you probably knew all that already...
  66.  
  67. Larry
  68.