When I was playing around with my scriptdist program, I needed to create parts of the Makefile.PL, although I wanted to fill in some of the specifics. One of the things that I put in there is my hook for test_via_harness. I already escaped some of the characters in there because they are special, but now this bit of code is going to show up inside a string, so I need to escape the special characters and the escapes that escape them. Eventually, this thing is double interpolated.
my($self, $perl, $tests) = @_;
return qq| $perl "-MTest::Manifest" |
qq|"-e" "run_t_manifest(\$(TEST_VERBOSE), '\$(INST_LIB)', |
The first time I ran this I got this really boggling output.
my($self, $perl, $tests) =
return qq| $perl "-MTest::Manifest" |
qq|"-e" "run_t_manifest(20 1002 1001 80 20TEST_VERBOSE), '20 1002 1001 80 20INST_LIB)', |
qq|'20 1002 1001 80 20INST_ARCHLIB)')"\n|;
What are all of those numbers? There is some really wierd stuff going on there, but I did not bother to stop to investigate. I just went through the string again and ensured that I escaped all of the special characters, and ended up with the result that I wanted, thinking I could easily remember what happened later. For a brief moment, something involving aliens from outer space flashed by my mind's eye, and after that, a relatively more realistic notion about localtime. Still, I left all that behind and finished scriptdist.
Later that night I made a test script to recreate those mystical numbers. Had I stumbled onto some odd Perl behavior? For instance, the value of a hash in a scalar context is a wierd fraction, assigning a list to a scalar ends up with the last element as the scalar's value, and if you use localtime at exactly at midnight on a Tuesday you get an interesting message from Chip Salzenberg. Well, not really---I just made that last one up.
I had to try a lot of different things before I got back to the combinations of letters, digits, and punctuation that showed me the strange behavior. Remember that I am already looking for goofiness, so I am ignoring common sense, sort of like the time in a training session I completely forget what -w does.
I finally got my simple test script to do the goofy thing.
The output shows me the goofy, space alien numbers.
20 1002 1001 80 20TEST_VERBOSE)
Then, reality starts to come back. Ah, Perl special variables! Okay, now I see that $( variable there. I was looking at the (TEST_VERBOSE) as a token with a $ in front of it---a beginner's (and, well, my) error.
I also know the $( and $) variables have something to do with group ids, because the $ are the user id special variables, and although perlvar has a mnemonic based on the convexity of the punctuation, I never remember it correctly. Why do I get all those numbers, though?
I took a trip to perlvar and discovered that since my machine, a Mac OS X box, supports simultaneous membership in multiple groups, $( is a space-separated list of those groups (which is different than a list of groups, mind you). Apparently on my box I am a member of a lot of groups.
Now, that solution poses another problem. What are those groups? I could use the NetInfo Manager application to find out, but that would probably involve the use of the touchpad and some clicking. No, I started off mucking things up in Perl, and I will finish by mucking up things in Perl, which I do with three little Perl programs (two too many).
perl -le 'print $(' | perl -ane '$"=qq|\n|; print qq|@F\n|' | perl -nle 'print scalar getgrgid($_)'
I found out that I am in these groups, although for some reason $( has gid 20 twice---perhaps because that is my primary group.
I could have Perl golf-ed this down a lot of characters, but why do more damage than I have already done?
"brian: Making stupid mistakes so you do not have to"