Path: utzoo!mnetor!uunet!husc6!mailrus!ames!umd5!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uicsrd.csrd.uiuc.edu!mcdaniel From: mcdaniel@uicsrd.csrd.uiuc.edu Newsgroups: comp.sources.d Subject: Re: How are YOU using perl? Message-ID: <42400005@uicsrd.csrd.uiuc.edu> Date: 18 Apr 88 05:30:00 GMT References: <235@ateng.UUCP> Lines: 93 Nf-ID: #R:ateng.UUCP:235:uicsrd.csrd.uiuc.edu:42400005:000:3500 Nf-From: uicsrd.csrd.uiuc.edu!mcdaniel Apr 17 23:30:00 1988 Here are some of my notes about perl, for what they're worth. These are points that appeared unclear to me at some time or another. 1) "each(x)" has one state variable per array, not per "each" call. For example, while (($i,$j) = each(foo)) { ($m, $n) = each(foo); ... } will iterate once through @foo ($#foo/2 loop iterations), not twice. (If foo has an odd number of elements, the loop above is an infinite loop.) 2) On the other hand, each ".." has its own state variable. Also, only the left-hand side is evaluated while it is false, and then only the right-hand side is evaluated. If you have side effects in the other part, they are not executed. 3) eval 'X' takes about the same time as X. (eval is the only way to simulate "first-class" file handles, associative arrays, et cetera.) 4) Lists are only one-dimensional. Sigh. 5) "@foo = (); print $#foo;" prints -1, even if $[ == 1. Similarly, "@foo = (); $foo[$[] = 3; print $#foo;" always prints 0. (So the statement on page 3 of the man page, about $#foo being the subscript of the last element, is false.) 6) On an Alliant FX/1 (a Motorola 68020-based machine), -1 % 2 == -1. I. e. "%" takes the sign of the dividend, not the divisor. However, this is probably dependent on how the "%" operator is implemented in C on your particular computer, which in turn is probably dependent on the hardware "mod" instruction (if any). 7) If you use a string in a numeric context, and the string contains non-numeric characters, it converts as many leading characters from the string as it can, and ignores the later ones. E. g. $a = '1e+:1'; $a = $a + 1; print $a; $a = 'abc'; $a = $a + 1; print $a; print 2 and 1 respectively. The following timing tests were done on an Alliant FX/1. Your mileage may vary. Void where prohibited. 8) The conditionals below are ranked in order of increasing execution time with VERY approximate normalized execution times. 1 if 1.02 unless 1.2 if () {;} 1.25 if (} {;} else {} 1.63 do {;} unless 1.64 do {;} if 1.8 && 2 ? () : 0 (where is a simple assignment statement, and is a boolean expression). Those last 2 lines suprised me a lot. I was expecting them to be the fastest, or at least equivalent to if-then or if-then-else. 9) Timing for the following statements enclosed in a "sub": 1 if () {;} else {} 1.74 ? : ( is a boolean expression, and is a variable reference, like $a.) 10) For the following statements exclosed in "sub max": 1 $max = pop(@_); while ($foo = pop(@_)) { $max = $foo if $max < $foo; } $max; 1.21 $max = pop(@_); for ($i = 0; ++$i <= $#_; ) { if ($max < ($foo = $_[$i])) { $max = $foo; } } $max; 11) Neither "max", nor "min", nor "abs", nor "power" is builtin. They're easy enough to code, though. 12) In re assigning an array to variables, as in ($a, $b, $c) = @foo; If @foo has more than 3 elements here, the extras will not be assigned. If @foo has less than 3 elements, the missing ones are considered ''. Following this rule, of course, ($a) = @foo; assigns the first element of @foo to $a. However, $a = @foo; assigns the LAST element of @foo to $a. @foo used in ANY scalar context refers to its last element. (E.g. 2+@foo is 2 plus the last element of @foo.) This makes sense if you think of the comma operator in perl or C: a = (1, 2); should assign 2 to a.