It seems like only yesterday we passed epoch 1000000000 when in fact it was nearly eight and a half years ago. On the other hand I remember epoch 1111111111 quite clearly since it was just before my birthday.
And now we come to another momentous epoch, that of 1234567890. I just happened to notice this as I was watching a Cyrus imapd logfile.
2009-02-13 23:31:30 UTC, by my reckoning. A good excuse for a pint, if you ask me.
A couple of usability bugs turned up when File::Path was dragged kicking and screaming into the third millennium, with its new options hash interface.
Refactoring the code introduced a nasty symlink chmod 777 error, and the heuristics for detecting the new way of calling rmtree and mkpath made the wrong call in some circumstances.
All should be fixed, and the code as it stands should be ready to be bundled with perl 5.8.9. To help this happen, could people give this a spin?
Notably, users of minicpan should see errors about uninitialized variables go away, and people who see spurious all-digits directories created in $HOME should also see them go away.
Also, is the documentation clear? Please lodge RT reports for any problems you encounter.
So, I have a database with a particularly nasty design decision. We have people who belong to cost centres, usually only one, but sometimes with a prorata on two cost centres. The programmer responsable for creating the table denormalised things, so rather than having
EMP1 UNIT1 50%
EMP1 UNIT2 50%
EMP2 UNIT3 100%
EMP3 UNIT1 100%
we have something that looks like
EMP1 UNIT1 UNIT2 50 50
EMP2 UNIT3 null 100 0
EMP3 UNIT1 null 100 0
That is, both cost centre ids in the same table, the second one usually null. It is a given that there will never be more than two. This table is of course an utter bitch to work with. Turns out we can cheat a bit, by only keeping track of the rate of the first centre, the second is just 100-first (which also helps cut down round-offs). Let us create a table to play with:
create table t1 (
id_person varchar(10),
rate number(5,2),
unit1 varchar(3),
unit2 varchar(3),
val1 number(10),
val2 number(10)
);
insert into t1 values ('alice', 1, 'U1', null, 10, 20);
insert into t1 values ('bob', 1, 'U2', null, 4, 8);
insert into t1 values ('carol', 0.5, 'U1', 'U2', 300, 600);
insert into t1 values ('david', 0.2, 'U1', 'U3', 6000, 8000);
Now I want the sum the values val1 and val2 by unit, keeping in mind that for 'david', VAL1 6000 * 0.2 = 1200 is summed to U1, and the difference, 4800, to U3. Similarly, for VAL2, 1600 to U1 and 6400 to U3. In other words, I want the following result set:
U1 1360 1920
U2 154 308
U3 4800 6400
Now the only way that I can see is to:
Treat all that as a derived table, and sum the results.
This gives the following:
select
S.UNIT UNIT
,sum(V1) V1_TOT
,sum(V2) V2_TOT
from (
select
unit1 UNIT
,sum(val1 * rate) V1
,sum(val2 * rate) V2
from
t1
group by
unit1
union select
unit2 UNIT
,sum(val1 - val1 * rate) V1
,sum(val2 - val2 * rate) V2
from
t1
where
unit2 is not null
group by
unit2
) S
group by S.UNIT
order by S.UNIT
That's pretty ugly. Is there a better way?
I just spent a while chasing a stupid bug. I have an big log directory that I have to clean up. The number of files caused the shell's wildcard expansion to fail. So I wrote some perl to move things around.
And it didn't do anything. To cut a long story short, I needed the total number of files in the directory. So I had something along the lines of:
perl -le 'print scalar(glob("*"))'
That does not return the number of files. It returns the name of the first file. Or the last. I don't care.
You have to force array context and throw it away:
perl -le 'print scalar(()=glob("*"))'
This prints 31192. I wish Perl didn't do this. Nice interview question though, I guess.
Just a note to myself, in case I ever need this again, and it may help someone else....
I have a boring 17" no-name cathode ray monitor at home, coupled to a Wintel box with a reasonably useful graphics chipset on the motherboard.
The chipset appears to know how to do a virtual screen or 3000 or so pixels square, and window the screen display onto it, not that I find this particularly useful, but anyway...
One of my children has a computer game that kicks the screen into a certain resolution, and when you quit, it resets the screen resolution back into this mega-enormous resolution, and the screen attempts to try and display it at 70-80 times a second and fails dismally, instead of just setting a viewport into it. I have no idea who's fault this is. The result is what Neal Stephenson might call a snowcrash.
Actually, it's not. The machine is still completely functional except that it looks like you're looking at encrypted TV without a decoder.
After a number of reboots, the machine finally gets the message and resets the resolution to something sane. No, Safe Mode doesn't work. When I return to normal mode after a Safe session, the screen remains scrambled.
So finally after having done this too many times, I realised was that all I needed to do was to note the keyboard shortcut sequence, and then I could land the beast on instruments only.
And here is the recipe:
Shift-Ctrl-Tab # select previous (i.e. last, right-most) display tab
At the point the screen realigns itself with reality again, and then I can go and choose some other resolution.
grmphlkrjmgna
The latest development version of File::Path (version 1.99_02) is winging its way around the world to a CPAN mirror near you. It needs to be tested on as wide a variety of platforms as possible. This includes Windows, VMS, OS/2, QNX, NFS file systems, AFS and anything else you can lay your hands on.
If all goes according to plan, it will be bundled with Perl 5.10, and it is also backwards-compatible all the way back to Perl 5.005 (and possibly earlier), which will allow older installations to be upgraded to the new version as well.
The main improvement is that instead of writing:
rmtree( ['/foo/bar/rat', '/zug/zwang'], 1, 1 );
... (quick, what do those positional parameters do?) one may now write the more self-documenting
rmtree( '/foo/bar/rat', '/zug/zwang',
{ verbose => 1, skip_others => 1 }
);
But all this needs to be tested as far as possible, to ensure that nothing has been broken during the renovations. Please report bugs on the File-Path RT queue (http://rt.cpan.org/Public/Dist/Display.html?Name=File-Path).
Thanks.
An item came up on the perl.org contact address the other day: someone was asking where to find Pex::Text since they couldn't install it.
My first stop was to try out a couple of things on search.cpan.org, but the results were a little too helpful, i.e., pages and pages of results or nothing at all.
So I fired up my second tool of choice, based on acme's most excellent Parse::CPAN::Packages and after a couple of regexp searches I was satisfied nothing remotely like it exists.
I then turned to a reputable search engine and ran a search on "Pex::Text" and the first page was what looked to be like sploit sites, written in various slavic and asian languages I have trouble identifying.
So I closed the ticket saying that the person was on their own. But for my own edification, I'd like to know if anyone has heard anything about it (what it does, what it's used for/in), just for the record (and the fact that reputable search engines will no doubt pick up on this journal in the future).
Dear Lazyweb,
I've just spent the better part of an hour searching the web and coming up blank, and finally coding up my own SQL statement to solve the following problem: given a two dates, how many years apart are they? I didn't want to use Oracle's date minus date equals number of days, because I wanted to avoid the hassle of dealing with leap years.
select
case
when (to_char(sysdate, 'MM' ) - to_char(to_date(:dt), 'MM')) > 0
then (to_char(sysdate, 'YYYY') - to_char(to_date(:dt), 'YYYY'))
when (to_char(sysdate, 'MM' ) - to_char(to_date(:dt), 'MM')) < 0
then (to_char(sysdate, 'YYYY') - to_char(to_date(:dt), 'YYYY')) - 1
else
case when (to_char(sysdate, 'DD' ) - to_char(to_date(:dt), 'DD')) >= 0
then
(to_char(sysdate, 'YYYY') - to_char(to_date(:dt), 'YYYY'))
else
(to_char(sysdate, 'YYYY') - to_char(to_date(:dt), 'YYYY')) - 1
end
end as "y"
--,(to_char(sysdate, 'MM' ) - to_char(to_date(:dt), 'MM')) as "m",
--,(to_char(sysdate, 'DD' ) - to_char(to_date(:dt), 'DD')) as "d"
from dual
I've tested a number of boundary conditions and it seems correct to me.
Now, after you stop sniggering, you may show me the function I overlooked that would have done this for me, or point out any obvious bugs.
I just a spent considerable amount of time to get Crypt::SSLeay installed. Far too much time. At first I blamed myself, my host, my OpenSSL installation, perl, everything.
Finally I searched the web and found the following message:
http://mail-archives.apache.org/mod_mbox/httpd-test-dev/200301.mbox/%3c5.2.0.9.
Turns out that there's a bug in the code, and a one-liner patch to SSLeay.xs fixes it. There's even an RT ticket on the matter. Grrr!
So, if you see the following warning in your build:
SSLeay.xs:252: warning: passing arg 2 of `SSL_set_info_callback' from incompatible pointer type
... and the test dumps core, then patch the source as follows:
--- SSLeay.xs.orig 2002-08-01 17:43:22.000000000 -0400
+++ SSLeay.xs 2003-01-29 21:41:17.000000000 -0500
@@ -109,6 +109,7 @@
SSLeay_add_all_algorithms();
SSL_load_error_strings();
ERR_load_crypto_strings();
+ SSL_library_init();
bNotFirstTime = 1;
}
RAND_seed(buf,sizeof buf);
And now it works, yay!
This article was posted to computer.risks recently.
Date: Tue, 04 Jul 2006 13:17:36 +0200
From: Peter B. Ladkin
Subject: B747 freighter crashThe Canadian TSB have issued the report on the 14 October 2004 crash of a Boeing B747 freighter on takeoff at Halifax airport, Nova Scotia.
According to a Flight International report by David Kaminski-Morrow (4-10 July 2006, p4), the TSB "says that the crew's misunderstanding of a laptop computer tool for calculating take-off performance led to the accidents. It concludes that the crew unwittingly transferred and used weight data from the aircraft's previous flight while calculating performance criteria for the next take-off. The obsolete data misled the crew to derive incorrect thrust settings and critical speeds for take-off."
The aircraft failed to lift off after rotation and overran the end of the runway by 250 meters, briefly lifting off but then striking an earth berm, severing the tail section and bringing the aircraft to earth again. All seven crew were killed.
I was deeply moved reading this. If it isn't already evident, piloting a 747 is not just a question of jockeying the thing down to the end of the runway and hitting the juice. So you put your faith in the numbers cranked out by a computer program since there are too many parameters for a person to take into account and deal with, and no-one has the numeracy skills any more to realise that things might be a little out of whack.
I wonder if the crew had a gut feeling of the unfolding events, based only on the note of the jet engines and feeling of acceleration. No doubt they knew something was amiss when the damned machine refused to haul itself into the sky at the expected time.
My heart goes out to the families left behind.