Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!decwrl!labrea!aurora!eos!ames!elroy!devvax!lwall From: lwall@devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.sources.bugs Subject: Re: Perl Bugs and Comments Message-ID: <1418@devvax.JPL.NASA.GOV> Date: 28 Feb 88 07:32:43 GMT References: <69600002@sushi> Reply-To: lwall@devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA. Lines: 167 In article <69600002@sushi> tchrist@sushi.UUCP writes: : A) $! is always 25 (ENOTTY), regardless of what I've just done. : The documentation says it should contain "the current value : of errno, with all the usual caveats". I think I understand how : things interract with errno, but I can't explain this one. I can't explain it either. It works fine here on both Sun and Vax. Is your errno declared to be something other than int maybe? Is your compiler blowing the cast to (double) in stab_str()? : B) Certain kinds of variable references misbehave when imbedded in a : string: : : "this $#ARGV in a string" prints "this ARGV in a string" : "this $_[$i] in a string" prints "this [i] in a string" : : where is the current input record; others are literals. The BUGS section of the manual says: You can't currently dereference array elements inside a double-quoted string. You must assign them to a temporary and interpolate that. The problem with implementing it is that I'd either have to do a run-time evaluation on the subscript expression, which can be very slow, or I'd have to decompose "this $_[$i] in a string" into "this " . $_[$i] . " in a string" I just haven't gotten around to doing it yet. Someday. That's why it's in the BUGS section. : Now for some things that are sadly lacking: : : 1) There is no perror() mechanism. I would like to be able to say : die "$file: $SYSERR[$!]" unless open(fd,$file); Yes, this is sadly lacking. Not difficult to add, either, so expect it soon. : 2) There is no mechanism for internal file globbing. Saying : @manfiles = split(' ',`ls /usr/man/man?/$arg.* 2> /dev/null`); : is such an overkill -- plus I must check $? as the bourne shell : returns the unglobbed string if it makes no match. Sometime soon. It's a little harder than SYSERR though, mostly because I have to incorporate portable directory reading routines. Turning a file glob pattern into a regular expression is fairly trivial. I already have the routine to do it in rn. As to syntax, I'm thinking of providing a glob('*.[ch]') function which returns an array. If you can think of a better way to do it, lemme know. If there are any PD globbing routines out there I'd like to know about those too. : 3) It would be nice if $ENV{'SHELL'} would be honored for `evals`. This is, unfortunately, a bug of popen(), not perl. For the moment you'd have to say $shell = $ENV{'SHELL'}; `$shell -c 'evals'`; : 4) There is no mechanism for "if" tests, like -e, -x, -w, -d, ... : Using the `eval` mechanism is clumsy, inefficient, and sometimes : impossible. For example, : : if ( `if [ -e a* 2> /dev/null ]; then echo 1; fi` ) { : : will succeed for just ONE a* file, not zero or more than one. I've been thinking about adding this for some time. While you can stat the file from within perl and pick apart the mode word, I wouldn't want to wish this on anyone, either the person trying to write it, or the person trying to read it. I suspect they'd simply be unary operators with a precedence a little higher than relationals and a little lower than math and concatenation operators. So you could say if (-r $foo . '.bak' || -r $foo) and have it work in the most intuitive manner. : 5) I wish I didn't have to use two statements for this: : $hours = $_[3]; : $hours =~ s/:.*//; : I would like to say : $hours = $_[3] =~ s/:.*//; : but in this context, perl says it's is a pattern-compare and returns : one or zero. I don't see any easy way to change this offhand. I'd hate to make the operation of =~ depend on its syntactic context, and I have to have =~ return a boolean in logical contexts. How about this: I might be able to convince perl that an assignment is a valid lvalue. Then you could say ($hours = $_[3]) =~ s/:.*//; That's within two charcters of what you wanted, though with inside-out semantics. And of course, the whole thing STILL returns a boolean. : 6) You can link but not symlink; if you're a BSD system this should be : possible. I suppose. Though I've resisted incorporating features that I know can't be used everywhere. This one's so useful, however, that I may break down and do it. Scripts using it would be no less portable than C programs that use it. : 7) I've had trouble with the array/scalar notation, as well as not : always being certain whether to use a $ or @ at all. I've always : worked it out, but it's somehow not very intuitive. Has anyone else : had this problem? The thing I find interesting is that nobody has EVER complained about my forcing them to put $ or @ on the front of every variable in sight, when awk and C don't do so. The main reason, apart from readability, is to let me add new keywords to the language without blowing all your old scripts out of the water because you happened to use $glob. As to your complaint, there are two parts to it. Let me see if you are saying what I think you are saying. 1) Scaler references are $foo. Array references are @foo. But array element references are $foo[$i]. Why not @foo[$i]? 2) There are some places in the language where $ and @ appear to be unnecessary. Where are these places? 1) Why not @foo[$i]? I dunno, it just came out the other way. I think of the $ or @ as a type mark for the whole term, not the type mark of the following identifier. I think in terms of the scaler value I'm really going to reference, not the route I took to get there. So my mental grouping of $foo[$i] is not <$foo>[$i] but rather $ Maybe I'm just strange in my head, but since there are places in the code where the type of the object determines whether the surrounding context does an array operation or a scaler one, I like to see the type of the whole object out in front. For example, of the following two items, I think the second is more intuitive: push(@array,@whatever[$i]); # illegal push(@array,$whatever[$i]); At a glance I know the second one is pushing a scaler value. Your mileage may vary, of course. 2) Where are $ or @ unnecessary? I don't think there's any place where $ is unnecessary. As for @, there are some array functions that KNOW that a particular argument is going to be an array, and so don't care if you put the @ or not. It never hurts to put it, though. I don't know if I can justify having optional @ typemarks. I could easily argue myself into wishing they were mandatory. Of course, that might break some perl scripts already in the world, so I probably will leave it as it is, but I suggest you always use @. Especially if it's @glob. :-) I hope I haven't lied too much... Larry Wall lwall@jpl-devvax.jpl.nasa.gov