
tchrist at perl
May 19, 2008, 4:11 PM
Post #18 of 22
(313 views)
Permalink
|
|
Re: Getopt::Long, + options, installperl, +v
[In reply to]
|
|
In his epistle <20080519090347.GO6780[at]plum.flirble.org>, Nicholas Clark wrote on Primidi, Prairial 1°, day 241 of the year CCXVI at 4:19:29: >On Sun, May 18, 2008 at 10:41:03PM -0600, Tom Christiansen wrote: >> Even in the rare case that what you want *isn't* there, I'd bet you a >> finely Belgian Trappist Ale of arbitrary size that Johan'd put your >> functionality in there for you right away in a jiffy. > "arbitrary sized Belgian Trappist Ale" - that's s *scary* concept. :-) > At least with small, finite sized ales I can count them, and when I lose > count I know I should have stopped (probably some time ago) Hey, just blame it on the grande and glorieuse Révolution française with their système métrique! :-) Voilà how well it all worked out for the second line of the current message! Or ask Lavoisier. :-( But I do *so* love metric time, too; don't you? It would give the world economy a *huge* boost if we were to all convert now. Plus I'd no longer be obliged to boringly preface my missives with the likes of At 10:03:47 2008-05-19, Nick Clark wrote: Or, dying of boredom, seek to go embellishing the Dickens (:-) out of it until it's as bello (NOT bellic!) as anyone could imagine (and few'd dare): On Monday at 10:03:47am BST [+0100], the 19th of May in anno domini 2008, one Mister Nicholas Clarke, Esq. has done us all the fine honour of having seen fit to graciously write: Well, ok, fine; maybe not quite *that* much. :-) But gosh, it's the prémier day of Prairial, and that's so cool. That's just a saying, you know, the cool part. We're expecting 92° tomorrow! and I grant you that if it felt much more like Germinal 'round these parts a few days ago, not even yet Floréal. But we just don't *have* spring here in Colorado. Instead, we have these radical oscillations between winter and summer of semi-random but ever-lengthening periodicity, ever back and forth again between them, and across both halves of the year. Starting only gradually with sudden fits and starts, and even more sudden setbacks, summer *eventually* wins this climatic tug of war, though at times not till nigh unto Midsummers Day itself. But only for a time, and with no guarantee of its continued abeyance. Which means I'm not quite foolhearty enough to put my tomatoes out yet. :-) But in return, summer sometimes pays winter surprise visits here, too. You just never know. The Old Norse were right: there really are but two seasons, at these given appropriate latitudes and/or altitudes. Let's get back to talking ale. Tell me, who can *really* know what all those silly Belgian measures add up when you can no longer nor count? Easier just to deal with halves and doubles. For example, if your alestein is half-full, or even half-empty on a ones-complement system, why, now you've just gone and pinted your quart! And if the barmaid of the establishment doesn't immediately upon seeing your sad and halvsied condition quickly top you off entirely unsupplicated and irremunerated, you're just not gettin' your quids' worth, and thus should frequent another public house; or perhaps even a private one :-) Plus who wants to use a vigesimal counting system, and why? "Et alor, that'll be only quatre-vingts dix-neuf today, M'sieur!" At least you'd be in Belgium where they have their nonantes. That way you wouldn't have to take your shoes off to count. :-) But *you* still have vigesimal pints, don't you now? At least now I'm told that "THEY"'re at long last relenting on pushing *their* cultural imperialism enough to let you folks keep your/our units. Well, not quite ours. Our liquid measures always nicely halve or double, being completely binary, making an *American* gallon of ale not one grain shy of the rather enticing- looking kilodram (2**10 drams), you know--or, if the non-hackers get their way again, I suppose a kibidram, but that sounds too much like a Kibo-gram to me. I still think base-10 just plain sucks for some kind of things. Gimme a duodecimal system any [12-hour] day. :-) Better yet, gimme a sexy sexagesimal system any [60-minute] hour or [60-second] minute, and cry Fie! on metric time. That way the shopkeeps can C<use integer> when making change: "That'll be two to the pound, ma'am." Or three. Or four. Or six. Or an even dozen. Why, just *look* at all those nice factors in 12 and 60! Makes your head go in circles, doesn't it now? And I'm not talking radians: Babylon shall be with us always. And look, I didn't even have to tell you whether the tomatoes weighed in at 3 to a pound, or whether that was the price the greengrocer was asking for them. Or both. How very perlish! >> But then I in turn gotta admit *I* should've used Getopt::Long >> all along. :-( I wouldn't do what I did, Nick, if I'd the >> whole thing thing to do over. I'd just thank Johan and use his >> code. I don't think you'll be sorry if you do. > I guess that there is one problem you may have had with using > Getopt::Long all along - I'd guess that some of your code > predates it. Most of my code is prey, not predator. :-( Heck, I've got scripts that antedate Perl itself. And this isn't even most of them from university, which are stuck on 9-track tapes nobody any longer has hardware readers for. % ls -lrt ~/scripts/ total 4592 -rwxr-x--- 1 tchrist 100 431 Jun 2 1987 getwin -rwxr-xr-x 1 tchrist users 214 Jan 20 1989 systail -rwxr-x--- 1 tchrist 100 483 Jul 24 1989 mergef -rwxr-x--- 1 tchrist 100 491 Aug 6 1989 redist -rwxr-xr-x 1 tchrist users 5499 Jul 28 1991 h2ph -rwxr----- 1 tchrist users 20610 Feb 23 1993 user -rw-r--r-- 1 tchrist 100 321 Apr 29 1993 tip -rw-r--r-- 1 tchrist users 337 Jan 11 1994 vi -rwxr-xr-x 1 tchrist 100 604 May 4 1994 ah -rwxr-xr-x 1 tchrist 500 1384 Feb 1 1996 Who -rw-r--r-- 1 tchrist 500 818 Feb 1 1996 W.oneill [...] The eldest of those, getwin, reads: #!/bin/csh -f if( "$1" =~ *:* ) setenv DISPLAY "$1" foreach x ( `xwininfo -root -children | sed -ne '/Child/s/^.*: //p'` ) xwininfo -id $x | awk \ 'BEGIN { ismapped = 0 } \ /Window name/ { temp = "" ; for(i = 5; i <= NF; i++) \ temp = temp $i ; \ winname = substr(temp, 2, length(temp)-2) } \ /IsMapped/ { ismapped++; } \ /Upper.*=.*x/ { outgeo = $4 ; } \ END { if(ismapped > 0) print winname " " outgeo }' end See what I mean about most of my code falling more into the prey set than the predator one? :-) And aren't you all glad Perl showed up? Otherwise, who *knows* what dark monsters I'd've brought to light by now but for that one, happy event? Even in Perl, memory is long. Think back to those pre-pod days when things started with: #!/usr/local/bin/perl 'di'; 'ig00'; Or when we'd blithely write code like: $cols = ($ENV{"TERMCAP"} =~ /:co#(\d+):/) ? $1 : 80; $PIPE= "who |"; open(PIPE) || die "$0: can't open $PIPE: $!\n"; That still works, you know, so kindly don't break it. :-) While some of those scripts there at the start of the list are "truly" ancient, almost all still run just fine. Well, or (often?) appear to. See any wee problem here? $now = time; $DELTA = 2*60*60; @mo = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec); open(UTMP,'/etc/utmp') || die "can't open utmp: $!"; chdir '/dev' || die "can't cd to /dev: $!"; open(TTYS, "/etc/ttys") || die "can't open /etc/ttys: $!"; Then again, if you miss that you can't cd to "/dev," I imagine you'll land in hotter water later. :-) Reminds me of the great 1984 paper entitled Can't Happen or /* NOTREACHED */ or Real Programs Dump Core in which the authors present the initially (ahem) intriguing question: In what program do we find the following code sequence: open("/", 0); dup(0); dup(0); --[tchrist here] Where you wait a minute, thinking and guessing, before you're gabberflasted to learn that-- V7 init, alas. There are two other occurrences, in which the opens are "open(tty, 2);" and "open(ctty, 2);". The author *knew*, by god, that those system calls could *never* fail. As a result, when the kernel file or inode tables fill, init fails to re-populate some terminals with init children and thus getty's. Thus those terminals will never inherit init's until the next crash or reboot. We know: the file and inode tables aren't supposed to fill, thus it **can't happen**. A common counter-argument is that in such a case there is nothing sensible to be done. Yet a moment's thought often reveals a better alternative than failing to check. In this case, since the code in question is running in a child of init, init can sleep briefly and try again if a system call such as dup() fails or if an open() fails due to resource exhaustion. See http://www.darwinsys.com/history/canthappen.html for details. Before Perl, I used anything--and EVERYTHING--to get the job done. Sometimes that meant using m4(1) as a system programming language; sometimes it meant using sh(1). For examples of using troff(1) as a systems programming language, though you'll have to hit up Larry, as that one's his bailiwick. I had lovely little shell scripts with pretty code like: device=/dev/rmt8 dd_noise='^[0-9]+\+[0-9]+ records (in|out)$' exec 3>&1 status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) | egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1` exit $status Catch that one? All it wants to know whether the dd(1) failed. Is that too much to ask? Apparently. Being the first stage of the pipeline, it wouldn't have been propagated: chthon(tchrist)% sh $ true | false $ echo $? 1 $ false | true $ echo $? 0 I used to rdist out syslog.conf files to bunches of machines, with extremely elaborate install-actions (ie, special "..." clauses) that remotely executed scripts on the target client that I'd WRITTEN IN m4! And not just the trivial "m4 distfile | rdist -f -", therefore. The good news was that m4's external-command-execution abilities, you can thus do anything. That, of course, was also the bad news, for I did so . :-) And of course, I used C. I calculate I cranked out over 100,000 of C code even before I hit grad school. I don't use C becaues I don't know it; rather, I don't use C because I *do*. :-) POP QUIZ! Without consulting any other document and relying only upon memory or deduction for your answer, write out in full the correct type-signature declaration, complete with ANSI prototypes, for the standard signal(3) function. You have just 30 seconds; start! I dare ya!! See what I mean? :-( Now sure, *you* can probably do it, Nick, and I know Larry could, too. But who else? Very few, very few. I'd even be willing to bet that this mailing list contains a statistically misrepresentative number of folks who could, since most previous pumpkings probably can, and the *REALLY* good Unix-C hackers, and just how many of *those* are there in the world? But come on, it is *not* a trivial problem--and so too is the very fact that it's not a trivial problem also a non-trivial problem, if you take my meaning. We all used C, but not out of love. I remember an email exchange with Larry over an rn(1) patch I sent him in this during this time at university in the mid 80s; again, PREPERLESCENTLY, but I can't read the 9-track. :-( Remember: the real code for Perl's "original" open2() function was written by me more than TWO YEARS BEFORE perl's public debut. I think I posted it on comp.unix.wizards or the comp.unix.programming as an undergrad. It began like this: /* process.c * * written by tom christiansen on Wed May 22 15:02:19 CDT 1985 * to open a socket pair and let the user read and write from * both sides. return -1 on error, otherwise put the correct * file pointers into *input and *output. * * CAVEAT UTILITOR: * you will block forever if one of the sides of the * pipes blocks because of too much in the buffer. */ See <URL: http://groups.google.com/group/comp.lang.perl/browse_frm/thread/3dc0c9132e81ebbc/f63de423e278454b?hl=en&lnk=st> for the rest of it, posted almost a decade later. It's probably *the* most didactically-commented C code I've ever written--though not the most dydact__ally-commented C code: I've never been a two-finger typist. :) Gosh, now I feel *really* old. BTW, for those few and intrepid souls who actually read all this from top to bottom without standing on their heads, you guys have done an ABSOLUTELY SMASHING-GOOD JOB with the 5.10 release. I'm stunned by how much very fine and very hard work you've all done, an honest compliment and accolade that I *never* give out in flattery, and am perhaps even too chary of awarding when credit is justly due. And credit is here most certainly due: THANK YOU! Sure, I've had some small troubles, but those were mostly with CPAN. For one thing, lynx fetching the gz stuff into tmp$$ files fails constantly, so I kept having to % cd .cpan/sources/modules % rename 's/\.tmp\d+$//' * And in fact, even that's not enough: you must omit the $ to get them all. And you have to *keep* doing this, over and over for those files one by one, until you manage to get yourself boostrapped enough to use something better. The other major problem was that my default process limits were too conservative for CPAN to be able to load up its datafiles without running out of memory. What I had... % limit cputime unlimited filesize unlimited datasize 76800 kbytes stacksize 4096 kbytes coredumpsize 0 kbytes memoryuse 111576 kbytes descriptors 64 memorylocked 37621 kbytes maxproc 128 ...just didn't cut it. I kept getting out-of-memory errors from CPAN.pm as it tried to load its huge dataset, and on more than one platform. FINALLY, I realized it was a resource limit, not a real bug, and thus % unlimit datasize % unlimit stacksize % unlimit memoryuse sufficed to get me back into action. Whew. But that now reminds me of an old faux-errno (ferrno?) of mine... --tom -- "EMACS belongs in <sys/errno.h>: Editor too big!" --tchrist
|