wickline's Journal http://use.perl.org/~wickline/journal/ wickline's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:12:31+00:00 pudge pudge@perl.org Technology hourly 1 1970-01-01T00:00+00:00 wickline's Journal http://use.perl.org/images/topics/useperl.gif http://use.perl.org/~wickline/journal/ So, You Want to Visit and/or Hold Ellie http://use.perl.org/~wickline/journal/28278?from=rss <p>Laura and I are zombies. We have not had enough sleep and so cannot think properly. Whenever we hold or look at Ellie, our brains turn to emotional mush and we just think warm fuzzy formless thoughts.</p><p>We have trouble remembering to take care of ourselves. It just doesn't occur to us to offer to hand Ellie to someone else. However, if you ask to hold Ellie, we'll be happy to let you share the joy we feel holding her. You just have to ask, because we won't think of it.</p><p>We're first time parents, so you'll want to wash up to relieve our anxiety. If you want to use a finger as a pacifier, please use Purell (we have plenty around) to sanitize the digit and put the nail side on her toungue to avoid scratching up the more delicate roof of her mouth.</p><p>If you want to visit, please just tell us. We're too brain-fried to be thinking up lists of everyone in town who may want to drop by and call folks. However, we'd be over-joyed to see you. Please just call and let us know you'd like to stop by. Suggest a couple of times. If we're changing diapers, sleeping, or whatever, we may not get to the phone as you call, but we'll return your call and most likely let you know that your suggested time is fine. If we have a doctor's appointment or something, we'll throw other times your way. We want you to visit!</p><p>If you're out of town, we want you to visit even more! Why? Well, because that means you'll be staying the night. In addition to your wonderful company, we may be able to get a bonus bit of baby-sitting. Just watching Ellie while we go on a walk together for half an hour would be a special treat.</p><p>Just as we're bad about inviting local folks to drop in, we're also bad about inviting out of town folks for longer stays. If you're intersted in swinging by, please let us know. We'd love to have you here!</p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-07T17:08:24+00:00 journal You Will Forget http://use.perl.org/~wickline/journal/28277?from=rss <p>I had heard in the past that there was an evolutionarily fortunate mild amnesia associated with labor. If women remembered how much labor hurt, they'd only ever have one child.</p><p>This may be true. I don't know.</p><p>I <em>do</em> know that sleep deprivation adversely affects memory, and labor is often followed by sleep deprivation for both the new mother and her partner. If you're going to be in labor soon, get in the habit of writting things down.</p><p>We live within walking distance of our hospital. Each of the nights we stayed there, I ran home to run a few errands and fetch a few things we wanted to have. Each time, I had a written list of things to do. Each time I did everything on the list. Each time, I later realized that I'd neglected to write something down, and so I had forgotten it.</p><p>A few days post-partum, I still needed lists. If I was getting seven things from the store, I'll forget most of them if they were not written down. It's now almost a week after Ellie's birth, and I'd probably only forget one thing.</p><p>In the first four days, you can only remember to do two things. One is the thing you're actually doing. The other is the one you're saying over and over in your head so you don't forget to do it next. If someone interupts you, then you may forget both of those! Sleep deprivation is nasty.</p><p>You'll also find that you can only do one thing at once. Normally, you may be able to talk on the phone and hear someone else in the room saying something relevant as you talk. You may even be able to tidy up a room with your free hand at the same time. That won't work anymore. If someone is trying to talk to you while you're on the phone, you may not even hear them. If you do, you'll surely loose track of what the person on the other end is saying. You can only do one thing at a time that requires any brain power. If you try to tidy up the room while you're on the phone, you'll end up walking aimlessly carrying the first thing you picked up because you won't be able to think about where it belongs while talking.</p><p>Do not expect too much of yourself at the outset. Laura and I were lucky enough to have folks staying with us to help out when we left the hospital. I'm sure things would have been even worse without this help. We'd certainly have got less sleep, which would have prolonged and worsened the condition.</p><p>You will forget things. Make lists.</p><p>You won't be able to multi-task. Add things to lists and do them later.</p><p>Good luck!</p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-07T16:49:58+00:00 journal The Proper Care and Feeding of New Parents http://use.perl.org/~wickline/journal/28275?from=rss <p>Ellie is our first child. She's currently six days and almost fifteen hours old. We're feeling much more competent as parents today than we did just a few days. I'm optimitstic that our confidence will continue to grow.</p><p>Those first few days are quite rough, though. As I've expressed it to so many folks over the phone, "We don't know how to take care of Ellie, but we remember to try. We know how to take care of ourselves, but we forget to try."</p><p>We've been blessed with good company during our early days, and I highly reccomend the same to anyone looking at having their first child (and probably even subsequent children, though I know less about that).</p><p>As a first time parent, you'll probably be spending 48 post-partum hours in the hospital (the max most insurance policies cover) so that you can soak up free advice from six shifts of nurses and a couple of lactation consultants. Free advice is good! Hopefully you'll let the nursing staff watch your infant between feedings at night so that you can get a pinch of sleep. However, it will be just two to three hours between feedings, and you'll be so excited that sleep will not come readily. You may not get much, and what you do get will be interupted.</p><p>You'll leave the hospital still high on new baby smell. When you get home, you'll spend your time either trying to take care of your child's needs or just holding her in your arms and smiling at her wonderful self.</p><p>This is where good company comes in. You're going to forget to make food for yourself. In a perfect world, someone would put food in front of you and offer to hold your child while you eat. Maybe someone will be making tons of extra food and filling up your freezer and fridge with tupperware and caserole pans and zip lock baggies full of meals you can reheat later. Perhaps someone will offer to hold your child while you get a shower, or while you and your spouse catch some quality time (most likely a nap at this point) together.</p><p>We were very fortunate to be surrounded by good company doing all of those things for us in our first days. It made a <em>huge</em> difference!</p><p>If you're going to be a first-time parent, try to get at least one person (in addition to your spouse) to come help you out in this fashion at the outset. You'll be quite glad you did!</p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-07T15:32:05+00:00 journal Photos of Ellie http://use.perl.org/~wickline/journal/28259?from=rss <p>The inital upload of <a href="http://media.wickline.org/2005_01_05_Ellies_First_Five_Days">Ellie's first five days</a> will be available for a little while longer. Snag any photos from there that you want. I'm currently uploading two new iPhoto exports and plan to maintain just two exports from now on.</p><p>One export will contain all photos with family and friends. I won't attempt to filter that feed, other than to remove photos after they're a few months old. That way you can download any photos with you that you want. The other export will be a montage of everything as of the upload date, but will be filtered to contain only a subset of the recent photos and a gradually diminishing quantity of the older photos. The half-life for older photos will depend primarily on how often I get around to updating these exports.</p><p>In both cases, the thumbnails are small but the actually images are very, very large. This is so that they'll print nicer. You may not want to click on the thumbnails if you're behind a slow connection.</p><p>Here's the two exports, last updated 2006 Jan 26: <a href="http://media.wickline.org/ellie/and_you/">You and Ellie</a> and also <a href="http://media.wickline.org/2006_01_26__Ellie_Montage/">Ellie's First 25 Days</a>.</p><p>UPDATE: <a href="http://media.wickline.org/ellie/montage">new montage 2006_07_09</a></p><p>Oh, and a new development... Some of the photos look like they'd make decent desktop images. On the mac, I prefer dark backgrounds on the right side of the screen, so that my icons have a stronger contrast with the desktop. On the pc, I prefer dark backgrounds on the left hand side for the same reason. I'm going to start collecting photos that look like good desktop images, and mirror them as needed to have them work on either platform. If you would like an Ellie desktop image on your PC, <a href="http://media.wickline.org/ellie/desktop/pc/">use these images</a>. If you would like an Ellie deskop image on your mac, <a href="http://media.wickline.org/ellie/desktop/mac/">use these ones</a>. If you want on one linux, then pick whichever fits the way you arrange your desktop.</p><p>The hospital has a service which took <a href="http://www.growingfamily.com/webnursery/babypage_view.asp?URLID=6N7V8E2L1N">a few photos of Ellie</a> too. The sweater, blanket, and hat were all hand-made by Laura. So was the baby<nobr> <wbr></nobr><tt>;)</tt> You can save these links if you just want jpgs: (<a href="http://www.growingfamily.com/images/customers/5585/2006/01/6N7V8E2L1N_1lg.jpg">1</a> <a href="http://www.growingfamily.com/images/customers/5585/2006/01/6N7V8E2L1N_2lg.jpg">2</a> <a href="http://www.growingfamily.com/images/customers/5585/2006/01/6N7V8E2L1N_3lg.jpg">3</a> <a href="http://www.growingfamily.com/images/customers/5585/2006/01/6N7V8E2L1N_4lg.jpg">4</a> ). They'll let you order prints of those photos to be mailed to you, if you'd like.</p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-06T07:33:49+00:00 journal links for Ellie fans http://use.perl.org/~wickline/journal/28229?from=rss <p>I'll use this journal entry to point folks to where to find Ellie info. If you want to send folks here, please use this URL &lt;<a href="http://ellie-info.wickline.org/">http://ellie-info.wickline.org/</a>&gt; as it will always point to an appropriate resource even if I stop using this journal.</p><p>You can find all entries in this journal at <a href="http://use.perl.org/journal.pl?op=display">http://use.perl.org/journal.pl?op=display</a> (entries in reverse chronological order). Just a few lines below is a table of contents to all Ellie-relevant journalings. I'll add entries as I think about writing them. I'll turn the text into a link when I get around to doing the actual typing.</p><p>For those of you hip to Firefox's live bookmarks and RSS agregators, feel free to use this RSS feed:<br><a href="http://use.perl.org/journal.pl?op=display;content_type=rss">http://use.perl.org/journal.pl?op=display;content_type=rss</a></p><p><strong>Table of Contents</strong><br><a href="http://use.perl.org/~wickline/journal/28227">Preface to These Journal Entries</a><br><a href="http://use.perl.org/~wickline/journal/28229">Table of Contents</a> (the very post you're currently reading)<br><a href="http://use.perl.org/~wickline/journal/28228">Labor and Delivery in Bullet Points</a><br><a href="http://wickline.org/ellie/age/">How Long Since Ellie Was Born?</a><br><a href="http://use.perl.org/~wickline/journal/28259">Photos of Ellie</a><br><a href="http://use.perl.org/~wickline/journal/28275">The Proper Care and Feeding of New Parents</a><br>Things We'd Do Differently<br><a href="http://use.perl.org/~wickline/journal/28277">You Will Forget</a><br><a href="http://use.perl.org/~wickline/journal/28278">So, You Want to Visit and/or Hold Ellie</a><br>Get Sleep!<br>Ellie's One Week Birthday<br>How are the Cats?<br>Ellie's Unbirthday<br>Suff Without Which We Could Not Live</p> wickline 2006-01-04T12:33:04+00:00 journal Ellie's birth in brief bullet points http://use.perl.org/~wickline/journal/28228?from=rss <p>I'm sleep deprived and may well get some times/stats wrong here. Correct me if you spot any errors (those of you who would know)</p><p>contractions started around 2am Saturday Dec 31st 2005</p><p>started timing contractions around 4am</p><p>14 contractions in 30 minutes</p><p>to hospital on advice of Jana (our friend and doula)</p><p>admitted around 5:45am to the last available room with 3cm dilation and full effacement, baby at -1 station</p><p>Laura labored without medication under increasingly longer and stronger contractions which rushed her to 7cm dilation by 9:30am. Doctor expected we would be pushing within an hour or so at that (very rapid!) rate of dilation.</p><p>During this period, we learned that the baby was tollerant of very few positions and her heart rate would plummet in most positions. Laura's bag of waters was ruptured so that they could apply a scalp monitor to her in order to have close continuous monitoring of this issue. We were advised at multiple points that a C-section might be required.</p><p>by 10:00am, the contractions were much, much worse but examinaion showed that we were still at 7cm. With the unusually rapid progression through labor, Lara had not had much time to acclimate to the contractions' severity. Also, C-sections can be done in much less time with a spinal tube already in place. We opted for an epidural.</p><p>the epidural was perfect. Laura could feel her legs, move them somewhat (once the initial boulus had worn off a bit), feel when contractions were occuring (but not feel their pain), feel when to push, and that she was pushing. The pain relief was uniform and very welcome.</p><p>a couple of hours after the epidural, we were <strong>still</strong> stalled at 7cm, and her contractions were actually slowing down. We opted for pitocin to get things moving again.</p><p>by 2:00 pm, we were close enough to 10cm that they had Laura do a couple of practice pushes to see if she would be able to push at that dilation and through the epidural. She could, so we started pushing.</p><p>All through this, we were still seeing concerning heart rate decelerations. Once Laura had pushed for a while, we were advised that a C-section was no longer likely, but that forceps or vaccume extraction might be required to accelerate delivery if things worsened. At the very end, they were ready to try these options, but Laura asked for a couple more pushes and threw every once of her reserve into the effort and delivered our daughter with a total of 75 minutes of pushing.</p><p>During delivery, we learned that the umbilical cord had been wrapped around her neck twice. Whenever a position change or pushing pressed her chin down toward her chest, the cord would be compressed cutting off her umbilical blood supply. This explained the decells we were worrying about all through labor. Laura cut the cord (yes, I'm squeamish).</p><p>She was born 4:21pm Sat Dec 31st 2005 7 pounds, 5.6 ounces, 19 inches long, 13.5 inches head circumference (and zero cone-head due to Laura's much relaxin-relaxed pelvis!), and 13.25 inches chest circumference. We had not yet picked her name.</p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-04T12:17:45+00:00 journal Elizabeth "Ellie" Rose Wickline http://use.perl.org/~wickline/journal/28227?from=rss <p>I've been a very inconstant journal writer here. I <em>think</em> that may be about to change. Our first daughter was born 4:21 in the afternoon of the last day of last year. I've been absolutely horrible about keeping up with my email. Now that Ellie is here, I'm sure I'll only get worse.</p><p>I'm going to start filling this space with the sort of baby tales I'd be copy/pasting into several emails if I were still on top of my inbox. When I advertise this journal to folks, they'll be able to tune in and comment at will.</p><p>I'm also going to be talking to myself. There's tons of stuff I'd like to remember the next time around, and sleep deprivation is murder on memory formation. Who knows... maybe someone else will find some handy nugget of info/experience/opinion in this stuff.</p><p>I am not going to worry much about typos and such. As I "type" this, it's 2:30am, I'm sitting in the dark living room in which my visiting mother in law is asleep. I'm in our nursing chair with an automan next to me on the left. Ellie in propped up on that automan in her boppy (ask google). My left hand is keeping her sleeping peacefully. My laptop is on my left knee, and one of our cats (Puck) is on my right knee. I'm hunting and pecking keystrokes with my right hand. In this sort of situation, I don't think that it's worth the time to worry about typos!</p><p>Anyhow, the content of this journal is likely to be strictly personal (or at least primarily so) from here on out. Please stay tuned if you want to read about Ellie. If you're looking for some text about symbol table slip-ups, or job postings, please avert your gaze.</p><p>OK, we are looking to fill five more new positions. Send me your resume so I can get the refferal bonus to help feed Ellie! What I've written about these positions in the past still applies, except that we're using svn more than cvs these days. Read more in this journal entry: <a href="http://use.perl.org/~wickline/journal/24764">http://use.perl.org/~wickline/journal/24764</a></p><p>(<a href="http://ellie-info.wickline.org/">more Ellie info</a>)</p> wickline 2006-01-04T10:49:53+00:00 journal Call me Ovid. Rentrak is hiring again http://use.perl.org/~wickline/journal/24764?from=rss <p>OK, I'm not Ovid, but Curtis did keep the perl public at large apraised of Rentrak job opportunities while he was working here. Now that he's gone and we happen to have some openings, I figure I'll post the banners this time.</p><p>Curtis has some very honest comments scattered in his journalling if you wanted to research before jumping.</p><p> &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://use.perl.org/journal.pl?op=list&amp;uid=2709">http://use.perl.org/journal.pl?op=list&amp;uid=2709</a></p><p>I started working at Rentrak a couple of weeks before Curtis. He and I worked together for somewhere around a month before he moved over to a different area on the same floor. The positions I'm plugging are not in the same area he worked in for the majority of his stay with Rentrak. We're the "research and development" group. We get to create new systems and then when they start making tons of money we fork off a support staff to maintain them.</p><p>I'd say that our area practices pair programming much more consistently (and without any issues of folks falling asleep<nobr> <wbr></nobr>;). We're more gung-ho about refactoring since we have multiple systems to develop and we don't want to repeat ourselves.</p><p>If you like test-driven development, pair programming, fun people, 40 hour work weeks, your choice of platform/editor for developing (although we have tons of cool tools hooked up for vim or emacs users), then send me your resume.</p><p> &nbsp; &nbsp; &nbsp; &nbsp; m-s-w-rtk-resumes-2005 [at] wickline [dot] org</p><p>and I'll ensure that it gets in the right hands.</p><p>We've been continuing to grow since before I was hired about two years ago. These are new positions as we're about to fork off half of our RnD group to support a maturing product.</p><p>-matt</p> wickline 2005-05-19T02:48:37+00:00 journal a colorful waste of time http://use.perl.org/~wickline/journal/22374?from=rss <p>It's <a href="http://use.perl.org/~pudge/journal/22326">Pudge's fault</a>, no it's <a href="http://use.perl.org/comments.pl?sid=24094&amp;cid=36877">Aristotle's fault</a>. OK, I guess it's really my own fault. I spent a silly amount of time getting the hilight script to handle nested parens in a fashion which didn't bug me...</p><p>I'll be curious to hear if it handles all of Aristotle's favorite test cases too.</p><p>-matt</p><blockquote><div><p> <tt>#!/usr/bin/perl -wnp<br> &nbsp; <br>use strict;<br>use Term::ANSIColor;<br>use Getopt::Std;<br> &nbsp; <br>our( @COLOR, $REGULAR_EXPRESSION, $LINE_NUMBER, $NUM_MATCHES, @START, @END, @PROCESSED );<br> &nbsp; <br>use constant ENTIRE_MATCH =&gt; 0;<br> &nbsp; <br>BEGIN {<br>&nbsp; &nbsp; getopts( 'c:' ) &amp;&amp; @ARGV or die &lt;&lt;"&nbsp; &nbsp; END_USAGE";<br>usage: $0 [ -c color ] pattern [ file... ] [ &lt; input ]<br>&nbsp; &nbsp; You can use capturing parens in your pattern.<br>&nbsp; &nbsp; If you provide multiple atrributes via the -c option,<br>&nbsp; &nbsp; the first will be used to color the portion matching<br>&nbsp; &nbsp; the pattern, the second will color the portion matching<br>&nbsp; &nbsp; the first capturing parens, the third will color the<br>&nbsp; &nbsp; portion matching the second capturing parens, etc.<br>&nbsp; &nbsp; Extra colors will be ignored. Extra parens will be<br>&nbsp; &nbsp; colored the same as the non-captured matching text.<br> &nbsp; <br>&nbsp; &nbsp; % cat notes.txt<br>financial notes...<br>\$25 I owed to "bob smith" on 20041211 explanation: brewfest&nbsp; # some meta data here<br>\$1 I paid to "sally johnson" on 20041212 explanation: sodas&nbsp; # some meta data here<br>\$25 I paid to "bob smith" on 20041213 explanation: cash&nbsp; &nbsp; &nbsp; # some meta data here<br>\$1 I recd from "sally johnson" on 20041215<br>\$42 I paid to "" on 200412157 explanation: top secret xmass<br>other notes...<br>\$100_000_000_000 might be nice to have, eh?<br>I wonder what I'm doing on tuesday next week.<br>I like pie.<br>&nbsp; &nbsp; % $0&nbsp; \\<br>&nbsp; &nbsp; -c'cyan,&nbsp; bold, red,&nbsp; &nbsp;green, yellow,&nbsp; &nbsp; &nbsp; &nbsp;magenta,&nbsp; &nbsp; blue,&nbsp; white on_red, bold&nbsp; &nbsp; '&nbsp; \\<br>&nbsp; &nbsp; &nbsp; &nbsp;'\\\$\\d+ (I (?:(owed)|(paid)|(recd)) \\S+) "([^"]*)" on (\\d+) *(explanation: (.+))?#?'&nbsp; \\<br>&nbsp; &nbsp; &nbsp; &nbsp;&lt; notes.txt<br>&nbsp; &nbsp; END_USAGE<br>&nbsp; &nbsp; # yes the above looks ugly, but it prints out a tidy usage example<br> &nbsp; <br>&nbsp; &nbsp; @COLOR = split<nobr> <wbr></nobr>/,/, our $opt_c || 'bold red';<br>&nbsp; &nbsp; $REGULAR_EXPRESSION = qr/@{[ shift ]}/;<br>}<br> &nbsp; <br>s{ $REGULAR_EXPRESSION }{&nbsp; paint_match( ENTIRE_MATCH )&nbsp; }gsex;<br> &nbsp; <br>sub init_match_info {<br>&nbsp; &nbsp; return unless $. &gt; ( $LINE_NUMBER || 0 );<br>&nbsp; &nbsp; $LINE_NUMBER = $.;<br>&nbsp; &nbsp; @START&nbsp; &nbsp; &nbsp; &nbsp;= @-;<br>&nbsp; &nbsp; @END&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= @+;<br>&nbsp; &nbsp; $NUM_MATCHES = $#END;<br>&nbsp; &nbsp; @PROCESSED&nbsp; &nbsp;= ();<br>}<br> &nbsp; <br>sub paint_match {<br>&nbsp; &nbsp; init_match_info();<br> &nbsp; <br>&nbsp; &nbsp; my $match = shift;<br>&nbsp; &nbsp; return $_ if $match &gt; $NUM_MATCHES;<br> &nbsp; <br>&nbsp; &nbsp; my( $result, $cursor ) = ( '', $START[ $match ] );<br> &nbsp; <br>&nbsp; &nbsp; for my $nested_match (&nbsp; $match + 1&nbsp;<nobr> <wbr></nobr>..&nbsp; $NUM_MATCHES&nbsp; ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; next if empty( $nested_match ) || $PROCESSED[ $nested_match ];;<br>&nbsp; &nbsp; &nbsp; &nbsp; last unless match_x_contains_match_y( $match, $nested_match );<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; $result<nobr> <wbr></nobr>.= paint_substr(&nbsp; $cursor,&nbsp; $START[ $nested_match ],&nbsp; $match&nbsp; );<br>&nbsp; &nbsp; &nbsp; &nbsp; $result<nobr> <wbr></nobr>.= paint_match(&nbsp; $nested_match&nbsp; );<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; $cursor = $END[ $#PROCESSED ];<br>&nbsp; &nbsp; }<br> &nbsp; <br>&nbsp; &nbsp; $result<nobr> <wbr></nobr>.= paint_substr(&nbsp; $cursor,&nbsp; $END[ $match ],&nbsp; $match&nbsp; );<br>&nbsp; &nbsp; $PROCESSED[ $match ]++;<br>&nbsp; &nbsp; return $result;<br>}<br> &nbsp; <br>sub paint_substr {<br>&nbsp; &nbsp; my( $start, $end, $match ) = @_;<br>&nbsp; &nbsp; return '' unless $end &gt; $start;<br>&nbsp; &nbsp; return colored(&nbsp; substr( $_, $start, $end - $start ),&nbsp; colors_for_match( $match )&nbsp; );<br>}<br> &nbsp; <br>sub empty{&nbsp; ! $END[ shift() ]&nbsp; }<br> &nbsp; <br>sub match_x_contains_match_y {<br>&nbsp; &nbsp; my( $x, $y ) = @_;<br>&nbsp; &nbsp; return(<br>&nbsp; &nbsp; &nbsp; &nbsp; ! empty( $x )<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; $END[ $x ] &gt; $START[ $y ]<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; $START[ $x ] &lt;= $END[ $y ]<br>&nbsp; &nbsp; );<br>}<br> &nbsp; <br>sub colors_for_match {<br>&nbsp; &nbsp; my $match = shift;<br>&nbsp; &nbsp; return $COLOR[ ENTIRE_MATCH ]<br>&nbsp; &nbsp; &nbsp; &nbsp; if (&nbsp; $match == ENTIRE_MATCH&nbsp; or&nbsp; ! $COLOR[ $match ]&nbsp; );<br>&nbsp; &nbsp; return map {<br>&nbsp; &nbsp; &nbsp; &nbsp; match_x_contains_match_y( $_, $match)&nbsp; ? $COLOR[ $_ ]&nbsp; : ();<br>&nbsp; &nbsp; } ENTIRE_MATCH<nobr> <wbr></nobr>.. $match;<br>}</tt></p></div> </blockquote> wickline 2004-12-20T00:02:27+00:00 journal Thanks Ingy, Autrijus, and Damian! http://use.perl.org/~wickline/journal/21099?from=rss <p>At OSCON I was salivating over a couple modules Damian used in his presentations. In a presentation on better interfaces, he indicated that those juicy tidbits would one day make it to CPAN.</p><p>Today is that day!</p><p>(or maybe yesterday was... whatever)</p><p><a href="http://search.cpan.org/dist/IO-Prompt">IO::Prompt</a></p><p><a href="http://search.cpan.org/dist/Smart-Comments">Smart::Comments</a></p><p>Sweet!</p><p>-matt</p> wickline 2004-09-28T23:55:46+00:00 journal thanks pudge! http://use.perl.org/~wickline/journal/19854?from=rss <p>I just realized today that the 'light' mode was back. Not sure how long it's been back, but I'm glad it has returned.</p><p>Thanks!<nobr> <wbr></nobr><code>:)</code></p><p>-matt</p> wickline 2004-07-15T00:12:59+00:00 journal When you think of spam... http://use.perl.org/~wickline/journal/17449?from=rss <p>...think of me!</p><p>I learned today that when users ask google <a href="http://google.com/search?q=%22how+to+get+spam%22">how to get spam</a>, I'm the first name that comes to mind.</p><p>A prof was looking into sources of spam on behalf of a student who was developing antispam software and dropped me an email after running that query.</p><p>I've also been google's favorite for "colorblind" for quite a while, which brings to mind the following idle trivia: It seems that tens of thousands of users have decided that the best way to get around their local webblocking software is to view porn through the colorblind web page filter.<nobr> <wbr></nobr>...yet another reason to hate webblocking software...</p><p>-matt</p><p>P.S.:<nobr> <wbr></nobr>...and for the sake of completness, I was google's favorite for "employment objective" back when I was still looking for work, but lost the honor (I think) due to not having updated the page in months.</p><p>P.P.S: <strong>to <em>avoid</em> spam</strong>, I now prefer to send mail from addresses which have the form foo-list-subscribe-bar-baz@example.com where foo/bar/baz tend to identify the specific contact/occasion, and example.com is my domain. Address-harvesting bots (so far) ignore list-subscribe addresses, but if they ever spam them, I'll be able to kill the specific address without invalidating other addresses. The 'list-subscribe' technique has allowed me to go without killing any of my ad-hoc addresses for about a year now.</p> wickline 2004-02-17T03:42:35+00:00 journal re-inventing the pageset wheel http://use.perl.org/~wickline/journal/13340?from=rss <p><a href="http://use.perl.org/~Matts/journal/13324">Matts asked about page set code</a>, and use.perl.org decided that my reply was sufficiently compressible that it probably wasn't meaninfull content... so I'm posting it here to see if I'm allowed to put meaningless things in my own journal<nobr> <wbr></nobr><tt>;)</tt></p><p>-matt</p><blockquote><div><p> <tt>=item C&lt;prepare_resultset_paging&gt;( I&lt;$set_size&gt;, I&lt;$page_size&gt;, I&lt;$curr_page&gt;, I&lt;$url&gt; )<br> &nbsp; <br>Given the size of a current result set (number of hits), the size of our result<br>pages (ie: showing a list of ten hits per page), and the number of our current<br>page (zero indexed: ie 0 for the first page in the result set), and the initial<br>URL (to which the zero-indexed page numbers will be appeneded)... Returns HTML for<br>links allowing the user to page through the result set. The links will include<br>a 'previous' and 'next' link where applicable, and will include links to jump<br>to up to eight other result pages by page number. Generally, the script will<br>prefer to show four pages before and four after, but for pages near either end<br>of the result set, that view may be shifted to continue showing eight other<br>pages.<br> &nbsp; <br>For a general idea, here's a textual representation of different output for<br>all of the pages in a twenty-page result set (_underlined_ items are links<br>and whitespace is only added to hilight patterns in the output)<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_next_ page[&nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp;_2_&nbsp; _3_&nbsp; _4_&nbsp; _5_&nbsp; _6_&nbsp; _7_&nbsp; _8_&nbsp; _9..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; &nbsp; &nbsp;_1_&nbsp; &nbsp;2&nbsp; &nbsp;_3_&nbsp; _4_&nbsp; _5_&nbsp; _6_&nbsp; _7_&nbsp; _8_&nbsp; _9..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; &nbsp; &nbsp;_1_&nbsp; _2_&nbsp; &nbsp;3&nbsp; &nbsp;_4_&nbsp; _5_&nbsp; _6_&nbsp; _7_&nbsp; _8_&nbsp; _9..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; &nbsp; &nbsp;_1_&nbsp; _2_&nbsp; _3_&nbsp; &nbsp;4&nbsp; &nbsp;_5_&nbsp; _6_&nbsp; _7_&nbsp; _8_&nbsp; _9..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; &nbsp; &nbsp;_1_&nbsp; _2_&nbsp; _3_&nbsp; _4_&nbsp; &nbsp;5&nbsp; &nbsp;_6_&nbsp; _7_&nbsp; _8_&nbsp; _9..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...2_&nbsp; _3_&nbsp; _4_&nbsp; _5_&nbsp; &nbsp;6&nbsp; &nbsp;_7_&nbsp; _8_&nbsp; _9_ _10..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...3_&nbsp; _4_&nbsp; _5_&nbsp; _6_&nbsp; &nbsp;7&nbsp; &nbsp;_8_&nbsp; _9_ _10_ _11..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...4_&nbsp; _5_&nbsp; _6_&nbsp; _7_&nbsp; &nbsp;8&nbsp; &nbsp;_9_ _10_ _11_ _12..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...5_&nbsp; _6_&nbsp; _7_&nbsp; _8_&nbsp; &nbsp;9&nbsp; _10_ _11_ _12_ _13..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...6_&nbsp; _7_&nbsp; _8_&nbsp; _9_&nbsp; 10&nbsp; _11_ _12_ _13_ _14..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...7_&nbsp; _8_&nbsp; _9_ _10_&nbsp; 11&nbsp; _12_ _13_ _14_ _15..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...8_&nbsp; _9_ _10_ _11_&nbsp; 12&nbsp; _13_ _14_ _15_ _16..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[&nbsp; _...9_ _10_ _11_ _12_&nbsp; 13&nbsp; _14_ _15_ _16_ _17..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...10_ _11_ _12_ _13_&nbsp; 14&nbsp; _15_ _16_ _17_ _18..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...11_ _12_ _13_ _14_&nbsp; 15&nbsp; _16_ _17_ _18_ _19..._ ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...12_ _13_ _14_ _15_&nbsp; 16&nbsp; _17_ _18_ _19_ _20_&nbsp; &nbsp; ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...12_ _13_ _14_ _15_ _16_&nbsp; 17&nbsp; _18_ _19_ _20_&nbsp; &nbsp; ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...12_ _13_ _14_ _15_ _16_ _17_&nbsp; 18&nbsp; _19_ _20_&nbsp; &nbsp; ]<br>&nbsp; &nbsp; _prev_ , _next_ page[ _...12_ _13_ _14_ _15_ _16_ _17_ _18_&nbsp; 19&nbsp; _20_&nbsp; &nbsp; ]<br>&nbsp; &nbsp; _prev_&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page[ _...12_ _13_ _14_ _15_ _16_ _17_ _18_ _19_&nbsp; 20&nbsp; &nbsp; &nbsp;]<br> &nbsp; <br>Note that the output reflects one-based indices even though the input<br>page number is zero-based and the href values will reference zero-based<br>indices. Also note that the url prefix arg should be HTML escaped if it<br>needs it. This method just slaps an int on the end and considers the<br>result to be valid for an href value.<br> &nbsp; <br>For sufficiently small result sets, fewer than eight links may be shown.<br> &nbsp; <br>For results sets having only three pages, only the prev/next links need to be<br>shown for the second page (as numbered 1/3 links are overly redundant). Result<br>sets having only (one or) two pages need not show numbered pages links either.<br> &nbsp; <br>Input is not validated. Caller is expected to have ensured sensible args.<br>The set size must be positive. The page size must be positive. The current<br>page must be non-negative and less than number of pages (which is calculated<br>from the set size and page size... and note that 'less than' is accurate<br>because the current page is zero-indexed).<br> &nbsp; <br>=cut<br> &nbsp; <br>sub prepare_resultset_paging {<br>&nbsp; &nbsp; my( $set_size, $page_size, $curr_page, $url ) = @_;<br>&nbsp; &nbsp; my $margin = 4; # in the midst of a large list, keep this many links on<br>&nbsp; &nbsp; &nbsp; &nbsp; # either side of our current page. Shift things about if we're near<br>&nbsp; &nbsp; &nbsp; &nbsp; # either end of our large list to keep 2*$margin links available<br>&nbsp; &nbsp; &nbsp; &nbsp; # for sufficiently short lists, the margin becomes less relevant<br>&nbsp; &nbsp; &nbsp; &nbsp; # and we just show as many links as there are<br>&nbsp; &nbsp; # determine how many pages are in the result set<br>&nbsp; &nbsp; my $num_pages = int( $set_size / $page_size );<br>&nbsp; &nbsp; $num_pages++ if $set_size % $page_size;<br>&nbsp; &nbsp; my $max_page = $num_pages - 1; # zero-indexed<br>&nbsp; &nbsp; return '' if $curr_page &gt; $max_page; # docs warn that caller shouldn't do this<br>&nbsp; &nbsp; my $l_margin = $margin;<br>&nbsp; &nbsp; my $r_margin = $margin;<br>&nbsp; &nbsp; if ( $curr_page &lt; $l_margin ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $diff = $l_margin - $curr_page;<br>&nbsp; &nbsp; &nbsp; &nbsp; $l_margin -= $diff;<br>&nbsp; &nbsp; &nbsp; &nbsp; $r_margin += $diff;<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; if ( $curr_page + $r_margin &gt; $max_page ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $diff = $curr_page + $r_margin - $max_page;<br>&nbsp; &nbsp; &nbsp; &nbsp; $r_margin -= $diff;<br>&nbsp; &nbsp; &nbsp; &nbsp; while (&nbsp; $diff--&nbsp; and&nbsp; ( $curr_page-$l_margin &gt; 0)&nbsp; ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $l_margin++;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; my @window = ($curr_page - $l_margin)<nobr> <wbr></nobr>.. ($curr_page + $r_margin);<br>&nbsp; &nbsp; my( $win_links, $prev, $next ) = ( '','','' );<br>&nbsp; &nbsp; if (&nbsp; @window &gt; 3&nbsp; or&nbsp; (@window == 3 and $curr_page != 1)&nbsp; ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; $win_links = join( ' ', map {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $_ == $curr_page<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? qq{&lt;strong&gt;@{[$_+1]}&lt;/strong&gt;}<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : qq{&lt;a href="$url$_#resultset"&gt;@{[$_+1]}&lt;/a&gt;}<br>&nbsp; &nbsp; &nbsp; &nbsp; } @window);<br>&nbsp; &nbsp; &nbsp; &nbsp; $win_links =~ s{^(&lt;a [^&gt;]+&gt;)}{$1...} if $window[0];<br>&nbsp; &nbsp; &nbsp; &nbsp; $win_links =~ s{&lt;/a&gt;\z}{...&lt;/a&gt;} if $window[-1] &lt; $max_page;<br>&nbsp; &nbsp; &nbsp; &nbsp; $win_links = "; page[&lt;small&gt; $win_links &lt;/small&gt;]";<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; $prev = qq{&lt;a href="$url@{[$curr_page-1]}#resultset"&gt;previous&amp;#160;page&lt;/a&gt;} if $curr_page;<br>&nbsp; &nbsp; $next = qq{&lt;a href="$url@{[$curr_page+1]}#resultset"&gt;next&amp;#160;page&lt;/a&gt;} if $curr_page &lt; $max_page;<br>&nbsp; &nbsp; return join( ', ', grep {$_} ($prev, $next) ).$win_links<br>}</tt></p></div> </blockquote> wickline 2003-07-09T03:52:40+00:00 journal Perl 6 Essentials http://use.perl.org/~wickline/journal/12333?from=rss <p>Oh Goodie!</p><p>Oh Goodie!</p><p>Oh Goodie!</p><p><a href="http://ora.com/catalog/perl6es/">I can't wait!</a></p><p>Hmmm....</p><p>How about a poll: How many editions of Perl 6 Essentials will be released before Perl 6.0?</p><p>a) zero: O'Reilly isn't really releasing this edition yet<br>b) just this one<br>c) N (because constants other than zero and one are icky)</p><p>-matt</p> wickline 2003-05-20T20:53:11+00:00 journal don't RTFM... it's too big http://use.perl.org/~wickline/journal/11951?from=rss <p>Why <strong>R</strong>ead <strong>T</strong>he <strong>F</strong> <tt>(?:</tt>riendly<tt>|...</tt>ing<tt>)</tt> <strong>M</strong>anual when you can just <a href="http://ora.com/catalog/rtfpg/">RTF Pocket Guide</a>?</p><p>-matt</p><p>(who really did take it that way <a href="http://ora.com/catalog/new.html">on first read</a>)</p> wickline 2003-05-01T19:08:27+00:00 journal Perl job opening posted http://use.perl.org/~wickline/journal/10992?from=rss <p>Washington Universtiy in Saint Louis (STL, MO, USA)</p><p>permanent, full time</p><p>read more at <a href="http://jobs.perl.org/job/680">http://jobs.perl.org/job/680</a>. If it says 'not available', I'm probably just fixing some dumb typo and waiting for approval. Try again in a few hours.</p><p>You can comment here if you want, but the link above tells you how you can actually apply for the position. Do not apply to me. All apps must go through HR.</p><p>The code you'd be inheriting is mostly mine, and we're hoping to hire soon enough that I can be around for the transition period. I'm likely leaving at some point in May.</p><p>-matt</p> wickline 2003-03-11T18:19:07+00:00 journal book shopping bookmarklets http://use.perl.org/~wickline/journal/10827?from=rss <p>This is in reply to a thread on <a href="http://use.perl.org/~nkuitse/journal/10810">boycotting Amazon</a>. I'd suggested my favorite alternative store and thought I'd follow up with a few bookmarklets which make book shopping simple.</p><p>First, know that I use Amazon to window shop. Their features make this so easy and interesting that I can't helpmyself. However, I prefer to shop where I get the best deal (and since Amazon never seems to have the best deal, I've never run into the 'boycott Amazon' issue). The following bookmarklets make it easy for me to window shop at amazon and then go somewhere else when I've found the book I want.</p><p>A bookmarklet is just a bookmark with a javascript URL. Use.perl.org strips javascript URLs from links, so I'll have to just dump the URLs here raw rather than letting you right-click and bookmark them. Sorry about that.</p><p>My favorite online bookstore is alldirect.com. They're cheap, they're efficient, and they've never messed up any of my many orders. (I order books online every few weeks, on average.) Their site is very minimalistic (like Amazon was back in the early days). The only glitch is that they don't list books not-yet-in-print, which most other online bookstores do.</p><p>I also like to comparison shop with other bookstores on occasion. However, alldirect is so often the best choice (and other stores so much less efficient or reliable) that I generally just go to alldirect.</p><p>I've got four book shopping bookmarklets on my Mozilla personal toolbar. They look like this:</p><blockquote><div><p> <tt>&nbsp; &nbsp; z2a&nbsp; z2$&nbsp; a2z&nbsp; a2$</tt></p></div> </blockquote><p>In my mind amaZon is 'z', alldirect is 'a', and my favorite bookstore comparison shopper is '$'. When I'm looking at a book's page on amazon, I can click 'z2a' to find that book at alldirect.com or I can comparison shop by clicking 'z2$'. If I happen to be looking at a book's page on alldirect.com, I can switch over to amazon with 'a2z' (maybe to find related titles) or to comparison shop with 'a2$'.</p><p>The comparison shopping searches will include shipping costs, provided you can tell the script where you'll be shipping to. To figure that part out, go to <a href="http://www.addall.com/">their home page</a> and fill in your shipping destination, state (for taxes), and currency (ie: USD). Then run a search for any old thing. Look at your resulting URL. Note the bits that look like</p><blockquote><div><p> <tt>&nbsp; &nbsp; dispCurr=USD&amp;location=10000&amp;state=OR</tt></p></div> </blockquote><p>You'll want to take your curency/location/state values and use them in the 'z2$' and 'a2$' bookmarklets below instead of my values.</p><p>Also note that the following bookmarklets work for me, in my browser. I use <a href="http://mozilla.org/">Mozilla</a>. If you use some other browser, you may find that these bookmarklets don't work. In that case, you'll need to adapt my javascript to work for your browser. A good way to do this would be to find some example bookmarklets which do work in your browser, and adapt them to use the code below. <a href="http://www.bookmarklets.com/tools/navigation/">This page</a> has an 'Up a Directory' bookmarklet in a number of forms for different browsers. That bookmarklet also changes the window's URL and would probably be a good starting point if you find a version that works for your browser.</p><p>And now for the bookmarklets. Use.perl.org will wrap these javascript URLs because they're so long. You'll need to remove the whitespace.</p><blockquote><div><p> <tt>z2a&nbsp; click from an amazon.com book page to the alldirect.com page<br> &nbsp; <br>javascript:void(location.href=("http://alldirect.com/book.asp?isbn="+loc ation.href.substr(location.href.indexOf("/ASIN/")+6,10)))<br> &nbsp; <br>z2$&nbsp; click from an amazon.com book page to comparison shopping<br> &nbsp; <br>javascript:void(location.href=("http://addall.com/New/submitNew.cgi? type=ISBN&amp;dispCurr=USD&amp;location=10000&amp;state=OR&amp;query="+location.href.substr(loc<nobr>a<wbr></nobr> tion.href.indexOf("/ASIN/")+6,10)))<br> &nbsp; <br>a2z&nbsp; click from an alldirect.com book page to the amazon.com page<br> &nbsp; <br>javascript:void(location.href=("http://www.amazon.com/exec/obidos/ASIN/" +location.href.substr(location.href.indexOf("isbn=")+5,10)))<br> &nbsp; <br>a2$&nbsp; click from an alldirect.com book page to comparison shopping<br> &nbsp; <br>javascript:void(location.href=("http://addall.com/New/submitNew.cgi? type=ISBN&amp;dispCurr=USD&amp;location=10000&amp;state=OR&amp;query="+location.href.substr(loc<nobr>a<wbr></nobr> tion.href.indexOf("isbn=")+5,10)))</tt></p></div> </blockquote><p>Happy shopping, and happy reading<nobr> <wbr></nobr><tt>:)</tt></p><p>-matt</p><p><strong>Update 2003_03_23:</strong> </p><p>Amazon no longer uses<nobr> <wbr></nobr><tt>/ASIN/</tt> in their URLs, but instead prefers to use<nobr> <wbr></nobr><tt>/-/</tt> in that place. The following bookmarklets take that into account...</p><blockquote><div><p> <tt>z2a&nbsp; click from an amazon.com book page to the alldirect.com page<br>javascript:void(location.href=("http://alldirect.com/book.asp?isbn="+loca<nobr>t<wbr></nobr> ion.href.substr(location.href.indexOf("/-/")+3,10)))<br> &nbsp; <br>z2$&nbsp; click from an amazon.com book page to comparison shopping<br>javascript:void(location.href=("http://addall.com/New/submitNew.cgi?t<nobr>y<wbr></nobr> pe=ISBN&amp;dispCurr=USD&amp;location=10000&amp;state=OR&amp;query="+location.href.substr(locat<nobr>i<wbr></nobr> on.href.indexOf("/-/")+3,10)))<br> &nbsp; <br>a2z&nbsp; click from an alldirect.com book page to the amazon.com page<br>javascript:void(location.href=("http://www.amazon.com/exec/obidos/tg/deta<nobr>i<wbr></nobr> l/-/"+location.href.substr(location.href.indexOf("isbn=")+5,10)))<br> &nbsp; <br>a2$&nbsp; click from an alldirect.com book page to comparison shopping<br>javascript:void(location.href=("http://addall.com/New/submitNew.cgi?t<nobr>y<wbr></nobr> pe=ISBN&amp;dispCurr=USD&amp;location=10000&amp;state=OR&amp;query="+location.href.substr(locat<nobr>i<wbr></nobr> on.href.indexOf("isbn=")+5,10)))</tt></p></div> </blockquote> wickline 2003-02-27T22:13:04+00:00 journal hiring a perl geek http://use.perl.org/~wickline/journal/10723?from=rss <p>About three months from now, some perl programmer will have my job, and I'll be unemployed... or so I hope.</p><p>Currently I spend most of my time documenting procedures and practices and reviewing existing code and code-level documentation with two coworkers who will inherit said code. They're both relatively new to perl. They've each written two or three perl scripts, and are otherwise primarily Uniface programmers (think "visual basic database apps" but w/o microsoft).</p><p>I learned yesterday that managment has agreed that it would be wise to hire a perl person as my replacement. They also agreed that it would be ideal if this person could be hired before I leave. So, I'm in the novel (for me) position of having some say in hiring my replacement, and being the primary person to evaluate their technical qualifications.</p><p>We'll be asking for code samples. I'm thinking that I'd like to see something over 100 lines to get a sense of what sort of documentation they typically include, how focused and reusable their subs are, whether they copy/paste instead of using subs/modules, etc. I'll also be asking some perl questions to get a feel for how familiar they are with common idioms, how they approach problems, how well they can take in someone else's code (mainly my code, since that's most of what they'll be working with for a while).</p><p>I've already got some questions/problems in mind, but I'm wondering if anyone has input about what sorts of questions they've found useful or useless in the past (from the perspective of the employer) and also whether folks have input from the perspective of the interviewee. Feel free to throw in non-technical questions if you'd like. I'll be asking some communication-skills-type questions too.</p><p>Also, does anyone have input about soliciting/reviewing code samples? What sorts of code have you requested (or had requested of you), or was the request always stated in very general terms? What sorts of things did you look for in the code?</p><p>If things move smoothly, I expect we'll be looking at resumes within a couple of weeks. Depending on the quantity and quality of applicants we may begin interviewing anywhere from three weeks to ??? from now. In any case, I've got some time before interviews and reviews of code would begin.</p><p>Any input?<nobr> <wbr></nobr>:)</p><p>Oh, for the curious, this would be in Saint Louis, MO (USA). I can't say more than that as all of the applications need to go through HR for legal reasons (so don't send me any resumes/code). Yes, I will be posting this opening to relevant perl fora once I've been cleared to do so... probably the perl jobs list, and to STL.pm, and in this journal. I'll look to see if perlmonks has an appropriate section too. I expect I'll be able to do that some time next week (maybe later if HR needs to clear the exact text I use in the posting).</p><p>-matt</p><p><strong>Update:</strong> the position is now <a href="http://jobs.perl.org/job/680">available</a>.</p> wickline 2003-02-21T14:24:46+00:00 journal it's a verb too http://use.perl.org/~wickline/journal/10369?from=rss <p> <b>perl</b> <a href="http://dictionary.reference.com/help/ahd4/pronkey.html">(p&#251;rl)</a> </p><p> <i>n.</i> </p><ol> <li>your favorite programming language </li><li>the interpreter of your favorite programming language </li></ol><p> <i>v. intr.</i> <b>perled, perling, perls</b> </p><ol> <li>to work in/with perl </li></ol><p> <i>v. tr.</i> </p><ol> <li>to modify using perl </li><li>to analyze/examine/study using perl </li><li>to re-create/duplicate/prototype using perl </li><li>to convincingly demonstrate the benefits of using perl </li></ol><p> This weekend I found myself using perl as a verb. Am I alone? </p><p> -matt </p> wickline 2003-02-03T19:21:41+00:00 journal jotto resources http://use.perl.org/~wickline/journal/9776?from=rss <p>in response to an article in <a href="http://use.perl.org/article.pl?sid=03/01/05/002202&amp;mode=flat&amp;tid=1">The Perl Review</a>...</p><p>I also got interested in Jotto a while back. A friend had showed me how to play and I wanted to show another friend, but I found it frustrating discussing strategies when I knew the word I wanted them to guess. So, I wrote a script to play against.</p><p> &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://wickline.org/j/">http://wickline.org/j/</a><br> &nbsp; &nbsp; &nbsp; &nbsp; Interface rather undocumented</p><p>The script allows you to track most of the things you normally want to track on paper when playing without a computer. If you want to play in a masochistic fashion, you can ignore all those interface elements.</p><p>Here's my jott-counting code if you're interested</p><blockquote><div><p> <tt>&nbsp; &nbsp; sub get_jotts {<br>&nbsp; &nbsp; &nbsp; &nbsp; my($probe, $target) = @_;<br>&nbsp; &nbsp; &nbsp; &nbsp; my %letters;<br>&nbsp; &nbsp; &nbsp; &nbsp; for ( split('',$target) )<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { $letters{$_}++ };<br>&nbsp; &nbsp; &nbsp; &nbsp; my $jotts = 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; for ( split('',$probe)&nbsp; )<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {$jotts++ if $letters{$_}-- &gt; 0};<br>&nbsp; &nbsp; &nbsp; &nbsp; return $jotts;<br>&nbsp; &nbsp; }</tt></p></div> </blockquote><p>Someone on a FWP list pointed out that you can optimize by generating a sub specific to the target word that in contexts where the sub will be called repeatedly with a single target word.</p><p>I've got a mammoth live-letter words list at</p><p> &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://wickline.org/fivers.tar.gz">http://wickline.org/fivers.tar.gz</a></p><p>I use a subset of that for my jotto game</p><p> &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://wickline.org/j/index.cgi?show=dict">http://wickline.org/j/index.cgi?show=dict</a></p><p>I heard of the "killer" strategy for winning Jotto on the FWP list, and found it too boring to play against, so didn't bother with a head-to-head play version. The basic notion is that every guess must be a possible win. Every time the computer guesses, it must make a guess that could be the target word in light of the scores of previous guesses.</p><p> &nbsp; &nbsp; &nbsp; &nbsp; select a number N between 1..5<br> &nbsp; &nbsp; &nbsp; &nbsp; Sort dictionary, first by rough order of word commonality<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then by the Nth letter<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This will ensure that guesses use more<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; common words before obscure ones, and<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; that guesses aren't always alphabetically<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; early... makes play a pinch more "real"<br> &nbsp; &nbsp; PROBE:<br> &nbsp; &nbsp; &nbsp; &nbsp; for each probe in dictionary<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; next PROBE if we've already guessed this probe<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for each term in our history of guesses<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; next PROBE unless score given to term was<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the same as it would get if probe were target<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if we get here, probe fits all term's scores<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; so return probe as our next guess<br> &nbsp; &nbsp; &nbsp; &nbsp; if we get here, no probe worked<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; so we don't know the word (or user mis-scored us)</p><p>In practice, the above method gives very little chance for a human to win, and so I didn't find it very fun to play against.</p><p>Happy jotting.<nobr> <wbr></nobr><tt>:)</tt></p><p>-matt</p> wickline 2003-01-05T17:22:03+00:00 journal How to get spam without even trying. http://use.perl.org/~wickline/journal/7781?from=rss <p>Sometimes folks ask why I don't want to be forwarded jokes unless I'm on BCC.<nobr> <wbr></nobr>...or they ask why I use such funny email addresses. I end up explaining this frequently, so I thought I would put it in the journal.</p><p>This was prompted by Matt's <a href="http://use.perl.org/~Matts/journal/7775">observation</a> that many hotmail users complain about getting spam even though they never give out their email address.</p><p>If you truely <strong>never</strong> give the email addie out (ie: never use the account to send mail or give it to anyone any other way), then you probalby won't get spam unless your username can be guessed. (Brute force username guesses against SMTP hosts are on the rise.)</p><p>However, if you phone your girlfriend and give her the address the day it was assigned to you, then you might never log in to the account at all and find out when you do so for the first time a year later that it is full of spam.</p><p>Suppose your girlfriend sent you only one message once she had your address.</p><p>She sent this hillarious story about a kitten which she knew you would appreicate. She also include her co-worker in the recipient list.</p><p>That co-worker had a great laugh, and forwarded it to five friends who like to share 'funny stuff' via email. One of those friends is on a mailing list where folks exchange 'funny stuff'. That friend forwards the message to the list.</p><p>Now, if these folks all just hit the forward button, then all of the original recpients' addresses are included in this post to the mailing list.</p><p>That list may have an address harvester subscribed.</p><p>That list may be accessible via NNTP where havesters lurk in abundance.</p><p>That list may be archived on the web, where harvesters are probably more common than on usenet these days.</p><p>Subscribers to the list may re-foward, further increasing chances of exposure.</p><p>It is possible that by telling your girlfriend your email address, you allowed that address to be exposed to spammers.<nobr> <wbr></nobr>...and once exposed, it's probably doomed. Spammers are an incestuous lot who constantly buy one anothers' lists, combine them and try to sell the new larger list for more money. I'm sure you've had plenty of spam trying to sell you email addresses, right? Once you get on one list, you have decent odds of being on oodles of lists.</p><p>If you use an address, it may get spam through no fault of your own. You can try to educate folks to use BCC when sending that kind of content (and don't send it yourself).<nobr> <wbr></nobr>...but the problem is that you just don't have control.</p><p>The only certain solution is to never use or advertise your email address.</p><p>A decent second-best is to use an infinite number of addresses. Try to use addresses specific to each contact/occasion/date/etc so that if the address ever gets spam, you can route it to the big bit bucket.</p><p>An interesting example: I once sent mail to Simon Cozens which he <a href="http://archive.develooper.com/perl6-meta@perl.org/msg00673.html">forwarded to a perl list</a>. That address started getting spam, and in addition related addresses started getting spam, revealing a bug in some common spam address-processing software I suppose:</p><blockquote><div><p> <tt>m_to_simon_cozens@wickline.org<br>&nbsp; &nbsp; &nbsp;simon_cozens@wickline.org<br>&nbsp; &nbsp; &nbsp; &nbsp;mon_cozens@wickline.org<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cozens@wickline.org<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;zens@wickline.org</tt></p></div> </blockquote><p>This series came from part of a Message-ID header:</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp;0.63e37fea@wickline.org<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3e37fea@wickline.org<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7fea@wickline.org</tt></p></div> </blockquote><p>None of the above addresses will get to me... they all get auto-trashed because they've been tainted and now receive spam. I could claim that <strong> <em>I never used that simon_cozens address</em> </strong> but the truth is that I did use it. One time. Now it gets spam. (and so do some releated addresses!)</p><p>When hotmail users say they never give out their address, I bet that they've at least used it once.</p><p>-matt</p> wickline 2002-09-17T18:02:04+00:00 journal horray for vacation! http://use.perl.org/~wickline/journal/7096?from=rss <p>Checking work email from home tomorrow, but not doing any real work... just kicking back and relaxing.</p><p>Friday will be some house cleaning so we can come back to a tidy nest <tt>(</tt>and so our friends won't see how we really live when they drop by to care for our cats<nobr> <wbr></nobr><tt>;)</tt> and packing.</p><p>Saturday we're flying to PDX, meeting up with friends who are also flying in, then driving up to spend some time with my mom, then further up to the Olympic National Forest.</p><p>Peace and friends and green and trees and sensible temperatures and no appreciable humidity and no work.</p><p>Horray!</p><p>-matt</p> wickline 2002-08-14T19:59:08+00:00 journal my second-least favorite experience on the 'net http://use.perl.org/~wickline/journal/7041?from=rss <p>...as long as I'm thinking about icky things...</p><p>Within a year of the sig-changing incident, some spammer used one of my addresses in the From header of their mail. The address was one of those 'free for life' ones and forwarded to my less-permanent school-provided address.</p><p>I won't mention the provider of that address, as they may have cleaned up their act since then.</p><p>I discovered a gazillion bounce messages in my inbox one day, some of which included the bounced message... which was spam. My address was in the From header. I also discovered a large volume of venomous hate mail from folks who had received the spam. While I felt bad for them, I was feeling worse for myself.</p><p>A few days later, I got a message directly to my school account from someone who had been unable to reach me at my 'permanent' address. It turns out that my account was closed. When I contacted support, they said that sending spam was in violation of the terms of use, and that they couldn't re-open the account. I provided them with instructions for the trivial From header forgery and they admitted that they hadn't done any investigation beyond looking at the From header... but they still wouldn't re-open the account.</p><p>At that point, I was happy to leave them. Sucky service sucks.</p><p>This was years ago. Hopefully they've invested in clues since then.</p><p>-matt</p> wickline 2002-08-12T00:35:57+00:00 journal my least favorite experience on the 'net http://use.perl.org/~wickline/journal/7040?from=rss <p>Until 1995 or 1996 (I forget the date, but I remember where I was living at the time) I had all sorts of information in my<nobr> <wbr></nobr>.sig file. The more useful info was name/phone/address.</p><p>I thought phone number and address (mailing address, that is) were useful because folks would have a convenient way to find my phone number if they needed to call me, or my address if they needed to mail me something. This was before everyone was carrying PDAs in their pockets, and the sig info <em>had</em> come in handy for folks in the past.<nobr> <wbr></nobr>...and I didn't think it could do any harm.</p><p>I was wrong. <tt><nobr> <wbr></nobr>:(</tt></p><p>One afternoon I got a phone call from some woman about some conversation she thought we had had in a white supremacist irc channel the evening prior.</p><p>If there's a group for which I have a prejudiced and unreasoned hatred, it's bigots. That may well make me a bigot myself, but I am <strong>not</strong> a white supremacist.</p><p>I was too upset to remember the details of our brief conversation, but the gist was she was sure she had the right person because she had the right combination of name, phone number and address. I was just as sure she had the wrong person.</p><p>Minutes after our phone conversation, my<nobr> <wbr></nobr>.sig was void of any 'useful' information.</p><p>The Internet lost some of its charm for me on that day. I don't suppose it actually was any different, but I sure learned to look at it through less-rosy glasses. <tt><nobr> <wbr></nobr>:/</tt></p><p><tt>-matt</tt></p> wickline 2002-08-12T00:08:06+00:00 journal So what's this button do, I wonder? http://use.perl.org/~wickline/journal/6994?from=rss <p>Everyone loves <a href="http://www.tuxedo.org/~esr/jargon/html/A-Story-About-Magic.html">mysterious switches</a>, right?</p><p>If you scroll down to the bottom of this page, there's a <a href="http://use.perl.org/my/misc">Misc</a> link. Click the link and you'll arrive at a Miscellaneous Options screen. That screen has a Save button.</p><p>Click the button and you'll be informed that "Option(s) Changed."</p><p>So, if you don't like the options life hands you, visit use.perl.org, eh?</p><p>Acutally, I didn't notice my options changing. Maybe I changed someone else's options? "Sorry" or "Your welcome", as appropriate.</p><p>-matt</p> wickline 2002-08-09T02:46:04+00:00 journal Holy vanity, Batman! http://use.perl.org/~wickline/journal/6969?from=rss <tt>Every several months or so, I type my name in a couple of variations<br>into google.<br><br>Why? Well, the first time I did it was after my natural father had found<br>me via the internet. I wanted to see just how easy it was to find me. I<br>wasn't trying to be hidden, or to be visible... I was just curious. So,<br>I typed in a handful of variations of my name in a few search engines.<br>This was in the pre-google days, and the altavista advanced search was<br>my favored search engine (back when altavista wasn't just another web<br>portal).<br><br>Every several months it occurs to me to repeat the excersize. I don't<br>really have any good reason for it. I'm not looking to see if I've been<br>keeping a low enough profile to be unobserved and I'm not looking to see<br>if I'm famous. I'm just wasting time basically. People do that at times,<br>ya know? I don't try all the search engines anymore, just google.<nobr> <wbr></nobr>...but<br>I still try a few variations of my name. I've found that there are a few<br>folks with my first and last name who are somewhat famous. I'm not one<br>of them. There are also a few less famous folks with my name. I've had<br>email from three strangers asking if I was their long lost relative or<br>high school classmate. I'm not.<br><br>Today I googled for 'wickline'. It's my last name, and I'd expected to<br>see oodles of strangers and an occasional relative. I did *not* expect<br>to see something of mine in the #3 spot!<nobr> <wbr></nobr>...but that's what I found!<br><br>As I type this,<br>&nbsp; &nbsp; http://google.com/search?q=wickline<br>has as the third hit<br>&nbsp; &nbsp; http://wickline.org/yapc/maps.html<br><br>Given the way google's page-rank system works, I'm interpreting that<br>result to indicate that this year's YAPC was more important than just<br>about anything wickline-related. YAPC beats out every wickline in the<br>world but two!<br><br>Bravo! Way to go YAPC!<nobr> <wbr></nobr>:)<br><br>On google images, there's a couple of nude women. I think you can<br>search for just about anything and find porn.<br><br>On google groups, strangers and relatives.<br><br>On google directory we find that use.perl.org is more important than<br>any wickline entry in dmoz.org (source data for google directory). My<br>name just happened to be on use.perl.org (because of that yapc post)<br>on the day it was last indexed by google, so as I type this, the u.p.o<br>page comes up on a search for wickline... and because u.p.o is better<br>ranked than any wickline-related page, it comes up first.<br><br>And if wasting time at google wasn't enough, I'm now wasting time here<br>talking about my waste of time.<br><br>What a waste of time.<nobr> <wbr></nobr>:) I think I need to get some sleep...<br><br>-matt<br>&nbsp; &nbsp; </tt> wickline 2002-08-08T00:09:03+00:00 journal mozilla custom keyword queries on steriods http://use.perl.org/~wickline/journal/6933?from=rss <tt>Do you use mozilla?<br>&nbsp; &nbsp; http://mozilla.org/<br><br>Do you use keywords?<br>&nbsp; &nbsp; http://www.mozilla.org/docs/end-user/internet-keywords.html<br><br>Do you use custom keyword queries?<br>&nbsp; &nbsp; http://www.mozilla.org/docs/end-user/keywords.html<br><br>Do you want your custom keyword queries to<br>&nbsp; &nbsp; - relace *all* instances of the token in your URI template?<br>&nbsp; &nbsp; - allow multiple arguments to be place in multiple places?<br>&nbsp; &nbsp; - allow some args to be url-encoded, but not others?<br><br>Then you want to take this perl code as a starting point for your own<br>CGI script or Apache module. Then set up a custom keyword to call that<br>script or module and you're home free (modulus one HTTP transaction per<br>call).<br><br>See also<br>&nbsp; &nbsp; http://use.perl.org/~miyagawa/journal/6929<br>&nbsp; &nbsp; http://use.perl.org/~miyagawa/journal/6930<br><br>This code predates the above, but miyagawa's posting reminded me<br>that other folks might find use for it...<br>&nbsp; &nbsp; http://bugzilla.mozilla.org/show_bug.cgi?id=124237<br>&nbsp; &nbsp; http://bugzilla.mozilla.org/attachment.cgi?id=69884&amp;action=view<br><br>I'm m_mozilla, so feel free to copy/adapt/whatever this code to<br>your heart's desire.<br><br>WARNING:<br>&nbsp; &nbsp; Slash wraped the long URLs.<br>&nbsp; &nbsp; The tests won't work until you unwrap them.<br><br>-matt<br><br>#!/usr/bin/perl -w<br>$::verbose = 0; # turn on to enable verbose testing (to STDOUT)<br>use strict;<br>print "testing...\n";<br>&amp;test_uri_template_code;<br>print "testing complete.\n";<br>sub build_uri ($$) { # Q=plain, q=encode<br>&nbsp; &nbsp; my( $uri_t, $query ) = @_;<br>&nbsp; &nbsp; return undef unless defined $uri_t;<br>&nbsp; &nbsp; return $uri_t unless $uri_t =~ m/%[qQ]\d*;/;<br>&nbsp; &nbsp; return &amp;empty_tokens( $uri_t )<br>&nbsp; &nbsp; &nbsp; &nbsp; unless ( defined $query and $query =~<nobr> <wbr></nobr>/\S/ );<br>&nbsp; &nbsp; $uri_t =~ s/%([qQ])0*(\d+);/%$1$2;/g;<br>&nbsp; &nbsp; $query =~ s/^\s+|\s+$//g;<br>&nbsp; &nbsp; my @terms = split(<nobr> <wbr></nobr>/\s+/, $query);<br>&nbsp; &nbsp; my @numeric_tokens = sort { $a &lt;=&gt; $b } (&nbsp; keys %{{<br>&nbsp; &nbsp; &nbsp; &nbsp; map&nbsp; { $_ =&gt; 1 }&nbsp; ( $uri_t =~ m/%[qQ](\d+);/g )<br>&nbsp; &nbsp; }}); # &lt;=&gt; sorted uniq numbers from %[qQ](\d+); tokens<br>&nbsp; &nbsp; while ( @terms and @numeric_tokens ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $term = shift @terms;<br>&nbsp; &nbsp; &nbsp; &nbsp; my $token = shift @numeric_tokens;<br>&nbsp; &nbsp; &nbsp; &nbsp; $uri_t =~ s{%([qQ])$token;}{&nbsp; $1 eq 'Q'<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ?&nbsp; $term&nbsp;<nobr> <wbr></nobr>:&nbsp; &amp;uri_encode( $term )<br>&nbsp; &nbsp; &nbsp; &nbsp; }ge;<br>&nbsp; &nbsp; } # now we're out of @terms and/or @numeric_tokens<br>&nbsp; &nbsp; return &amp;empty_tokens( $uri_t ) unless @terms;<br>&nbsp; &nbsp; return $uri_t unless $uri_t =~ m/%[qQ]\d*;/;<br>&nbsp; &nbsp; $uri_t =~ s{%([qQ]);}{&nbsp; $1 eq 'Q'<br>&nbsp; &nbsp; &nbsp; &nbsp; ?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;join( '+', @terms )<br>&nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>:&nbsp; uri_encode(&nbsp; join( ' ', @terms )&nbsp; )<br>&nbsp; &nbsp; }ge;<br>&nbsp; &nbsp; return $uri_t;<br>}<br>sub empty_tokens ($) {<br>&nbsp; &nbsp; local $_ = shift; s/%[qQ]\d*;//g; return $_;<br>}<br>sub uri_encode {<br>&nbsp; &nbsp; return undef unless $_[0];<br>&nbsp; &nbsp; my $txt = shift;<br>&nbsp; &nbsp; # use a real look-up table in mozilla; faster than this:<br>&nbsp; &nbsp; $txt =~ s/([^a-zA-Z0-9~._\-])/$1 eq' '?'+':sprintf("%%%02X",ord($1))/ge;<br>&nbsp; &nbsp; return $txt;<br>}<br>sub test_uri_template_code {<br>&nbsp; &nbsp; # keywords containing '_x_' have malformed URI templates, and<br>&nbsp; &nbsp; # the test results will need to not treat bad tokens as tokens<br>&nbsp; &nbsp; %::keywords2templates = qw{<br>&nbsp; &nbsp; &nbsp; &nbsp; a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%q<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%q1<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%qx<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%qx;<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_5&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%q0<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_6&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%q01<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%1;<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%20;<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_9&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/%1$q<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_10&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://www.alldirect.com/^%1$q<br>&nbsp; &nbsp; &nbsp; &nbsp; a_x_11&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://www.alldirect.com/%qabout.asp<br>&nbsp; &nbsp; &nbsp; &nbsp; isbninfo&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://www.amazon.com/exec/obidos/ASIN/%q1;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q1;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q01;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q001;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q000000001;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_5&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q0;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_6&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q00000000;<br>&nbsp; &nbsp; &nbsp; &nbsp; isbnbuy_7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://www.alldirect.com/book.asp?isbn=%q00000700;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q1;&amp;symbols=%q2;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q7;&amp;symbols=%q025;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q7;&amp;symbols=%q;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_x_1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%qq;&amp;symbols=%q;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_x_2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%;&amp;symbols=%0q;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_reverse&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q2;&amp;symbols=%q1;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_reverse_1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q001;&amp;symbols=%q000;<br>&nbsp; &nbsp; &nbsp; &nbsp; chart_reverse_2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://quote.fool.com/Chart/chart.asp?time=%q;&amp;symbols=%q0;<br>&nbsp; &nbsp; &nbsp; &nbsp; bughunt&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;<nobr>b<wbr></nobr> ug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;v<nobr>a<wbr></nobr> lue0-0-0=%q;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q;&amp;field0-0-2<nobr>=<wbr></nobr> short_desc&amp;type0-0-2=substring&amp;value0-0-2=%q;&amp;field0-0-3=status_whiteboard&amp;type<nobr>0<wbr></nobr> -0-3=substring&amp;value0-0-3=%q;<br>&nbsp; &nbsp; &nbsp; &nbsp; bughunt_first_term_only&nbsp; &nbsp; &nbsp;http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;<nobr>b<wbr></nobr> ug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;v<nobr>a<wbr></nobr> lue0-0-0=%q0;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q0;&amp;field0-0<nobr>-<wbr></nobr> 2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=%q0;&amp;field0-0-3=status_whiteboard&amp;t<nobr>y<wbr></nobr> pe0-0-3=substring&amp;value0-0-3=%q0;<br>&nbsp; &nbsp; &nbsp; &nbsp; bughunt_ordered_terms&nbsp; &nbsp; &nbsp; &nbsp;http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;<nobr>b<wbr></nobr> ug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;v<nobr>a<wbr></nobr> lue0-0-0=%q0;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q1;&amp;field0-0<nobr>-<wbr></nobr> 2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=%q2;&amp;field0-0-3=status_whiteboard&amp;t<nobr>y<wbr></nobr> pe0-0-3=substring&amp;value0-0-3=%q3;<br>&nbsp; &nbsp; &nbsp; &nbsp; owner_a_bughunt_queryb&nbsp; &nbsp; &nbsp; http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;b<nobr>u<wbr></nobr> g_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;va<nobr>l<wbr></nobr> ue0-0-0=%q;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q;&amp;field0-0-2=<nobr>s<wbr></nobr> hort_desc&amp;type0-0-2=substring&amp;value0-0-2=%q;&amp;field0-0-3=status_whiteboard&amp;type0<nobr>-<wbr></nobr> 0-3=substring&amp;value0-0-3=%q;&amp;email1=%q0;&amp;emailtype1=exact&amp;emailassigned_to1=1<br><nobr>&nbsp;<wbr></nobr> &nbsp; &nbsp; &nbsp; reporter_a_bughunt_queryb&nbsp; &nbsp;http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;<nobr>b<wbr></nobr> ug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;v<nobr>a<wbr></nobr> lue0-0-0=%q;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q;&amp;field0-0-2<nobr>=<wbr></nobr> short_desc&amp;type0-0-2=substring&amp;value0-0-2=%q;&amp;field0-0-3=status_whiteboard&amp;type<nobr>0<wbr></nobr> -0-3=substring&amp;value0-0-3=%q;&amp;email1=%q0;&amp;emailtype1=exact&amp;emailreporter1=1<br>&nbsp; &nbsp; &nbsp; &nbsp; anyemail_a_bughunt_queryb&nbsp; &nbsp;http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;<nobr>b<wbr></nobr> ug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;v<nobr>a<wbr></nobr> lue0-0-0=%q;&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=%q;&amp;field0-0-2<nobr>=<wbr></nobr> short_desc&amp;type0-0-2=substring&amp;value0-0-2=%q;&amp;field0-0-3=status_whiteboard&amp;type<nobr>0<wbr></nobr> -0-3=substring&amp;value0-0-3=%q;&amp;email1=%q0;&amp;emailtype1=exact&amp;emailassigned_to1=1&amp;<nobr>e<wbr></nobr> mailreporter1=1&amp;emailqa_contact1=1&amp;emailcc1=1&amp;emaillongdesc1=1<br>&nbsp; &nbsp; &nbsp; &nbsp; val_mozilla_page&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2F%q;<br>&nbsp; &nbsp; &nbsp; &nbsp; val_mozilla_page_to_html_v&nbsp; http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2F%q1;&amp;doctype=%q;<br><nobr>&nbsp;<wbr></nobr> &nbsp; &nbsp; &nbsp; drivefromhome_to_a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://maps.yahoo.com/py/ddResults.py?newaddr=123+Home+Ave&amp;newcsz=12345&amp;taraddr<nobr>=<wbr></nobr> %Q1;&amp;tarcsz=%q2;<br>&nbsp; &nbsp; &nbsp; &nbsp; drivefrom_a_to_b&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://maps.yahoo.com/py/ddResults.py?newaddr=%Q1;&amp;newcsz=%q2;&amp;taraddr=%Q3;&amp;tar<nobr>c<wbr></nobr> sz=%q4;<br>&nbsp; &nbsp; &nbsp; &nbsp; trans_parturl_a_from_b_2c&nbsp; &nbsp;http://fets3.freetranslation.com:5081/?Language=%q2;%2F%q3;&amp;Url=%q1;&amp;Sequence=<nobr>c<wbr></nobr> ore<br>&nbsp; &nbsp; &nbsp; &nbsp; trans_parturl_a_from_b_2c_1 http://fets3.freetranslation.com:5081/?Language=%q22;%2F%q33;&amp;Url=%q11;&amp;Sequenc<nobr>e<wbr></nobr> =core<br>&nbsp; &nbsp; &nbsp; &nbsp; trans_parturl_a_from_b_2c_2 http://fets3.freetranslation.com:5081/?Language=%q00022;%2F%q033;&amp;Url=%q000011;<nobr>&amp;<wbr></nobr> Sequence=core<br>&nbsp; &nbsp; &nbsp; &nbsp; trans_parturl_a_from_b_2c_3 http://fets3.freetranslation.com:5081/?Language=%q00022;%2F%q;&amp;Url=%q0;&amp;Sequenc<nobr>e<wbr></nobr> =core<br>&nbsp; &nbsp; &nbsp; &nbsp; trans_from_a_2b_parturl_c&nbsp; &nbsp;http://fets3.freetranslation.com:5081/?Language=%q1;%2F%q2;&amp;Url=%q3;&amp;Sequence=<nobr>c<wbr></nobr> ore<br>&nbsp; &nbsp; };<br>&nbsp; &nbsp; my %canonical_testcases = (<br>&nbsp; &nbsp; &nbsp; &nbsp; # for each testcase, [q{query string}, q{expected resuting URI}]<br>&nbsp; &nbsp; &nbsp; &nbsp; 'a' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{doesn't matter what args you put here, they should all be ignored},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.alldirect.com/},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'isbninfo' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{0596000529},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.amazon.com/exec/obidos/ASIN/0596000529},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{0596000529 additional args ignored. Book title is Creating Applications with Mozilla},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.amazon.com/exec/obidos/ASIN/0596000529},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{&nbsp; &nbsp; 0596000529 initial whitespace also ignored},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.amazon.com/exec/obidos/ASIN/0596000529},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'isbnbuy' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{0764545884},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.alldirect.com/book.asp?isbn=0764545884},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{0764545884 additional args ignored. Book title is Mozilla Source Code Guide with CDROM},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://www.alldirect.com/book.asp?isbn=0764545884},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'chart' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{1mo aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=1mo&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{3mo aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=3mo&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{ytd aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=ytd&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{2yr aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=2yr&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{all aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=all&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{ytd msft},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=ytd&amp;symbols=msft},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{&nbsp; &nbsp; 1mo&nbsp; &nbsp; aapl&nbsp; &nbsp; whitespace and extra args ignored},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=1mo&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'chart_reverse' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{ aapl&nbsp; 1mo&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;like above, but for those who prefer reversed syntax},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://quote.fool.com/Chart/chart.asp?time=1mo&amp;symbols=aapl},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'bughunt' =&gt; [ # bonus: bug 98749 gets fixed too!<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{custom keywords},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=custom+keywords&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=c<nobr>u<wbr></nobr> stom+keywords&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=custom+keywo<nobr>r<wbr></nobr> ds&amp;field0-0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=custom+keywords}<nobr>,<wbr></nobr> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{not suck},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=not+suck&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=not+suck<nobr>&amp;<wbr></nobr> field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=not+suck&amp;field0-0-3=status<nobr>_<wbr></nobr> whiteboard&amp;type0-0-3=substring&amp;value0-0-3=not+suck},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'bughunt_first_term_only' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{tabs&nbsp; &nbsp; &nbsp;and additional args are ignored},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=tabs&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=tabs&amp;field0-<nobr>0<wbr></nobr> -2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=tabs&amp;field0-0-3=status_whiteboard&amp;<nobr>t<wbr></nobr> ype0-0-3=substring&amp;value0-0-3=tabs},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'owner_a_bughunt_queryb' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{ben@netscape.com&nbsp; custom keywords},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=custom+keywords&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=c<nobr>u<wbr></nobr> stom+keywords&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=custom+keywo<nobr>r<wbr></nobr> ds&amp;field0-0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=custom+keywords&amp;<nobr>e<wbr></nobr> mail1=ben%40netscape.com&amp;emailtype1=exact&amp;emailassigned_to1=1},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{peterv@netscape.com&nbsp; white-space: pre},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=white-space%3A+pre&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-<nobr>1<wbr></nobr> =white-space%3A+pre&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=white-<nobr>s<wbr></nobr> pace%3A+pre&amp;field0-0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=white-s<nobr>p<wbr></nobr> ace%3A+pre&amp;email1=peterv%40netscape.com&amp;emailtype1=exact&amp;emailassigned_to1=1}, <br><nobr> <wbr></nobr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'reporter_a_bughunt_queryb' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{asa@mozilla.org&nbsp; crash causes},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=crash+causes&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=cras<nobr>h<wbr></nobr> +causes&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=crash+causes&amp;field<nobr>0<wbr></nobr> -0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=crash+causes&amp;email1=asa%4<nobr>0<wbr></nobr> mozilla.org&amp;emailtype1=exact&amp;emailreporter1=1},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'anyemail_a_bughunt_queryb' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{hewitt@netscape.com&nbsp; tooltip},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=tooltip&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=tooltip&amp;f<nobr>i<wbr></nobr> eld0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=tooltip&amp;field0-0-3=status_wh<nobr>i<wbr></nobr> teboard&amp;type0-0-3=substring&amp;value0-0-3=tooltip&amp;email1=hewitt%40netscape.com&amp;ema<nobr>i<wbr></nobr> ltype1=exact&amp;emailassigned_to1=1&amp;emailreporter1=1&amp;emailqa_contact1=1&amp;emailcc1=1<nobr>&amp;<wbr></nobr> emaillongdesc1=1},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{bryner@netscape.com}, # leaves normal query part empty, makes bugzilla work for very long time<nobr> <wbr></nobr>:/<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://bugzilla.mozilla.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW<nobr>&amp;<wbr></nobr> bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;<nobr>v<wbr></nobr> alue0-0-0=&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=&amp;field0-0-2=shor<nobr>t<wbr></nobr> _desc&amp;type0-0-2=substring&amp;value0-0-2=&amp;field0-0-3=status_whiteboard&amp;type0-0-3=su<nobr>b<wbr></nobr> string&amp;value0-0-3=&amp;email1=bryner%40netscape.com&amp;emailtype1=exact&amp;emailassigned_<nobr>t<wbr></nobr> o1=1&amp;emailreporter1=1&amp;emailqa_contact1=1&amp;emailcc1=1&amp;emaillongdesc1=1},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'val_mozilla_page' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{mozorg.html},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2Fmozorg.html},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{ports/fizzilla/Cocoazilla.html},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2Fports%2Ffizzilla<nobr>%<wbr></nobr> 2FCocoazilla.html},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'val_mozilla_page_to_html_v' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{ports/fizzilla/Cocoazilla.html HTML 4.01 Strict},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2Fports%2Ffizzilla<nobr>%<wbr></nobr> 2FCocoazilla.html&amp;doctype=HTML+4.01+Strict},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{ports/fizzilla/Cocoazilla.html XHTML 1.0 Transitional},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://validator.w3.org/check?uri=http%3A%2F%2Fmozilla.org%2Fports%2Ffizzilla<nobr>%<wbr></nobr> 2FCocoazilla.html&amp;doctype=XHTML+1.0+Transitional},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'drivefromhome_to_a' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{999+EndHere+Ave 56789},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://maps.yahoo.com/py/ddResults.py?newaddr=123+Home+Ave&amp;newcsz=12345&amp;tarad<nobr>d<wbr></nobr> r=999+EndHere+Ave&amp;tarcsz=56789},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{666+Brimstone+Ave 00666},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://maps.yahoo.com/py/ddResults.py?newaddr=123+Home+Ave&amp;newcsz=12345&amp;tarad<nobr>d<wbr></nobr> r=666+Brimstone+Ave&amp;tarcsz=00666},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'drivefrom_a_to_b' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{111+StartHere+Blvd 12345&nbsp; 999+EndHere+Ave 56789},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://maps.yahoo.com/py/ddResults.py?newaddr=111+StartHere+Blvd&amp;newcsz=12345<nobr>&amp;<wbr></nobr> taraddr=999+EndHere+Ave&amp;tarcsz=56789},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{111+StartHere+Blvd 12345&nbsp; 999+EndHere+Ave 56789&nbsp; &nbsp; all other args ignored},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://maps.yahoo.com/py/ddResults.py?newaddr=111+StartHere+Blvd&amp;newcsz=12345<nobr>&amp;<wbr></nobr> taraddr=999+EndHere+Ave&amp;tarcsz=56789},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'trans_parturl_a_from_b_2c' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{mozilla.org English Spanish},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FSpanish&amp;Url=mozilla<nobr>.<wbr></nobr> org&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mozilla.org English French},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FFrench&amp;Url=mozilla.<nobr>o<wbr></nobr> rg&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mozilla.org English German},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FGerman&amp;Url=mozilla.<nobr>o<wbr></nobr> rg&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mozilla.org English Italian},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FItalian&amp;Url=mozilla<nobr>.<wbr></nobr> org&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mozilla.org English Norwegian},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FNorwegian&amp;Url=mozil<nobr>l<wbr></nobr> a.org&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mozilla.org English Portuguese},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FPortuguese&amp;Url=mozi<nobr>l<wbr></nobr> la.org&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{mx.yahoo.com Spanish English},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=Spanish%2FEnglish&amp;Url=mx.yaho<nobr>o<wbr></nobr> .com&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{de.yahoo.com German English},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=German%2FEnglish&amp;Url=de.yahoo<nobr>.<wbr></nobr> com&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'trans_from_a_2b_parturl_c' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [ q{German English de.yahoo.com},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=German%2FEnglish&amp;Url=de.yahoo<nobr>.<wbr></nobr> com&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{Spanish English mx.yahoo.com},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=Spanish%2FEnglish&amp;Url=mx.yaho<nobr>o<wbr></nobr> .com&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{English Italian mozilla.org},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FItalian&amp;Url=mozilla<nobr>.<wbr></nobr> org&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],[ q{English French mozilla.org},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; q{http://fets3.freetranslation.com:5081/?Language=English%2FFrench&amp;Url=mozilla.<nobr>o<wbr></nobr> rg&amp;Sequence=core},<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; );<br>&nbsp; &nbsp; for my $keyword ( keys %canonical_testcases ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; for my $pair ( @{$canonical_testcases{$keyword}} ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;report_on_keyword_with_input( $keyword, @$pair );<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; my %additional_testcases = (<br>&nbsp; &nbsp; &nbsp; &nbsp; # like above, but for catching bizarre bugs. As bugs come up,<br>&nbsp; &nbsp; &nbsp; &nbsp; # fix them and add a relevant test case or two in here.<br>&nbsp; &nbsp; );<br>&nbsp; &nbsp; for my $keyword ( keys %additional_testcases ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; for my $pair ( @{$additional_testcases{$keyword}} ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;report_on_keyword_with_input( $keyword, @$pair );<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>}<br>sub report_on_keyword_with_input {<br>&nbsp; &nbsp; my( $keyword, $query, $expected ) = @_;<br>&nbsp; &nbsp; my $uri_t = $::keywords2templates{ $keyword };<br>&nbsp; &nbsp; my $result = &amp;build_uri( $uri_t, $query );<br>&nbsp; &nbsp; if ( defined $result ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $ok = $result eq $expected;<br>&nbsp; &nbsp; &nbsp; &nbsp; if ( $ok and $::verbose ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "... Correct URI when expanding:&nbsp; $keyword $query\n";<br>&nbsp; &nbsp; &nbsp; &nbsp; } elsif ( !$ok ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "!!! Unexpected URI when expanding:&nbsp; $keyword $query\n";<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "&nbsp; &nbsp; &nbsp; &nbsp; looking for:&nbsp; $expected\n";<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "&nbsp; &nbsp; &nbsp; &nbsp; but I found:&nbsp; $result\n";<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; } else {<br>&nbsp; &nbsp; &nbsp; &nbsp; print "!!! Undefined URI when expanding:&nbsp; $keyword $query\n";<br>&nbsp; &nbsp; }<br>}<br><br></tt> wickline 2002-08-06T15:19:47+00:00 journal Editor holy war spills into unfamiliar terrain http://use.perl.org/~wickline/journal/6876?from=rss <tt>http://barebones.com/products/bbedit.html<br><br>Sure, we're all sick of editor wars. We've got our favorite tools, and<br>we're so much more familiar with them that we're more efficient using<br>those tools than any others.<br><br>If you've recently purchased a T?iBook (and it sounds like a great many<br>of you have), then you may be finding that your favorite editor doesn't<br>work quite as handily in MacOS X as you'd like. It just doesn't fit in<br>with your newly-raised user-interface expectations and doesn't use the<br>strengths of the operating system to your advantage.<br><br>If you're feeling a wee bit dissatisfied, try BBEdit. It is IMHO (and<br>in many other folks' HOs) the best editor available on any platform,<br>and is only available for the Mac. It not only uses the MacOS to your<br>advantage (applescriptable, recordable, and attachable, quicktime<br>integration, services), but also integrates well with perl, python,<br>assorted shell scripting (and lets you set your default shell).<br><br>I don't get any kickback for convincing folks to use BBEdit. I just<br>think that it's so much better than the alternatives that those of<br>you who haven't tried it are really doing yourselves a disservice.<br><br>I had my employer buy me a mac so that I could use BBEdit. I told them<br>that they'd get more than their money back in my increased productivity<br>and I wasn't kidding.<br><br>A brief laundry list of some of the features:<br><br>&nbsp; &nbsp; World-class support. You contact them, and you get answers<br>&nbsp; &nbsp; &nbsp; &nbsp; back from the folks who actually write the program.<br>&nbsp; &nbsp; &nbsp; &nbsp; They also have very high quality mailing lists with<br>&nbsp; &nbsp; &nbsp; &nbsp; very active particpation from the developers.<br><br>&nbsp; &nbsp; best perl syntax coloring I've ever seen<br>&nbsp; &nbsp; &nbsp; &nbsp; (yes, I've seen vim and emacs)<br>&nbsp; &nbsp; &nbsp; &nbsp; also does a zillion other languages, but I don't care<br>&nbsp; &nbsp; &nbsp; &nbsp; so much about those<br><br>&nbsp; &nbsp; perl scripts and filters handily integrated<br>&nbsp; &nbsp; as well as pod-reading, perldoc lookup, syntax checking,<br>&nbsp; &nbsp; running the current file<br><br>&nbsp; &nbsp; PCRE find/replace including multi-file search/replace<br>&nbsp; &nbsp; with file filters to indicate which files to process<br><br>&nbsp; &nbsp; menu of your perl subs (menu does headers and named<br>&nbsp; &nbsp; &nbsp; &nbsp; anchors in HTML documents, similar handy things<br>&nbsp; &nbsp; &nbsp; &nbsp; in other languages)<br><br>&nbsp; &nbsp; user-configurable key bindings<br><br>&nbsp; &nbsp; convenient edit via ftp<br>&nbsp; &nbsp; &nbsp; &nbsp; also integrates well with other ftp clients<br><br>&nbsp; &nbsp; worksheets (hybrid of text document and unix shell)<br><br>&nbsp; &nbsp; find-differences and selectively apply changes in<br>&nbsp; &nbsp; either direction<br><br>&nbsp; &nbsp; handy DTD- and context-sensitive HTML markup tools<br><br>&nbsp; &nbsp; integration with ToolServer, SourceServer, CodeWarrior,<br>&nbsp; &nbsp; Dreamweaver Absoft Fortran, Mac OS X Developer Help,<br>&nbsp; &nbsp; your favorite shell, your favorite AppleScript editor,<br>&nbsp; &nbsp; your favorite everything.<br><br>&nbsp; &nbsp; So many useful features that every time I re-read the<br>&nbsp; &nbsp; manual, I find a new one which will benefit me.<br><br>If the above doesn't at least pique your curiosity, then maybe BBEdit isn't<br>for you. If you're interested, you can get a free 'crippleware' version of<br>the editor (BBEdit Lite) to get a little taste. The real thing is *so* much<br>better though.<br><br>http://barebones.com/products/bbedit_lite/bbedit_vs_bbedit_lite.html<nobr> <wbr></nobr> <br> <br>-matt</tt> wickline 2002-08-03T17:21:33+00:00 journal dump of module version information http://use.perl.org/~wickline/journal/6252?from=rss <tt>mako132 was looking for a way to get version info for<br>each module use'd by his script.<br><br>&nbsp; &nbsp; http://use.perl.org/~mako132/journal/6244<br><br>I replied with a ~20 line END block which should do the<br>trick. I thought I might find the code handy myself one<br>day, so I thought I'd stash it in my journal as well for<br>ease of finding. ((code at end of journal entry))<br><br>Maybe that's a use for this journal... post odd bits of<br>code that don't have any associated project, invite any<br>readers to critique/improve/ridicule said code, look at<br>code years in the future when I can better do the same<br>to it.<br><br>-matt<br> (still deciding what to do with this journal thing)<br><br>END { no strict 'refs';<br>&nbsp; &nbsp; for my $k ( sort keys %INC ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; ( my $module = $k ) =~ s{[:/\\]}{::}g;<br>&nbsp; &nbsp; &nbsp; &nbsp; $module =~ s{\.pm$}{};<br>&nbsp; &nbsp; &nbsp; &nbsp; my $version = ${"${module}::VERSION"};<br>&nbsp; &nbsp; &nbsp; &nbsp; if ( defined $version ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $version = "\$${module}::VERSION = $version\n";<br>&nbsp; &nbsp; &nbsp; &nbsp; } else { # maybe they didn't use ALLCAPS<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; my @found = (<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; map { defined ${"${module}::$_"}<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;? qq(\$${module}::$_ = ${"${module}::$_"}) : ()<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; grep { m/^version$/i }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keys %{"${module}::"}<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $version = !@found<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? "($module&nbsp; version number not found)\n"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : join( "\n", @found );<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; # if you want, print this to a log file instead:<br>&nbsp; &nbsp; &nbsp; &nbsp; print "$version $module&nbsp; loaded from&nbsp; $INC{$k}\n\n";<br>&nbsp; &nbsp; }<br>}<br></tt> wickline 2002-07-10T14:03:07+00:00 journal Wheeee! YAPC was fun! http://use.perl.org/~wickline/journal/6110?from=rss <tt>(and so is this journal thing, or maybe it's just 'cause I'm a wee<br>bit punchy from lack of sleep... we'll find out in future days)<br><br>Highlights (Letterman style)<br><br>&nbsp; &nbsp; #10 the weather could have been substantially worse (really!)<br>&nbsp; &nbsp; &nbsp;#9 being paid to have nothing but fun for three days<br>&nbsp; &nbsp; &nbsp;#8 finding little ways to pitch in with assistance<br>&nbsp; &nbsp; &nbsp;#7 seeing more women (I think) than at YAPC::NA 2001<br>&nbsp; &nbsp; &nbsp;#6 laughing my ass off (especially allison's &amp; gnat's l.Talks)<br>&nbsp; &nbsp; &nbsp;#5 being local so I didn't have to miss Laura for a week<br>&nbsp; &nbsp; &nbsp;#4 seeing some interesting ideas in code (YAML, abigail's OO)<br>&nbsp; &nbsp; &nbsp;#3 seeing the perl community *qua* community<br>&nbsp; &nbsp; &nbsp;#2 catching up with folks from far places<br>&nbsp; &nbsp; &nbsp;#1 meeting neat new people (Riley would have to be the most new)<br>&nbsp; &nbsp; &nbsp;#0 great company every day and evening, Wed though Sat!<br><br>Lolights<br><br>&nbsp; &nbsp; #4 gnat's 'something something' eleventh-hour slot-filler<br>&nbsp; &nbsp; &nbsp; &nbsp;turned out to be something else at the last minute. I<br>&nbsp; &nbsp; &nbsp; &nbsp;have yet to see him speak, and was looking forward to<br>&nbsp; &nbsp; &nbsp; &nbsp;whatever 'something something' might have been. Next time.<br>&nbsp; &nbsp; &nbsp; &nbsp;Silver lining: even though I still didn't get to see him<br>&nbsp; &nbsp; &nbsp; &nbsp;speak for his l.Talk, the movie was fucking hillarious.<br><br>&nbsp; &nbsp; #3 MJD wasn't quite his usual animated and focused self<br>&nbsp; &nbsp; &nbsp; &nbsp;when giving his red flags talk on Friday morning.<br>&nbsp; &nbsp; &nbsp; &nbsp;Silver lining: in reading the slides (half of the YAPC<br>&nbsp; &nbsp; &nbsp; &nbsp;proceedings!) I found a flag I need to watch myself.<br>&nbsp; &nbsp; &nbsp; &nbsp;I can think of a few scripts where I do the icky<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (...) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (...) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (...) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#<nobr> <wbr></nobr>...<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else {<nobr> <wbr></nobr>... } # tertiary error<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else {<nobr> <wbr></nobr>... }&nbsp; &nbsp; # secondary error<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else {<nobr> <wbr></nobr>... }&nbsp; &nbsp; &nbsp; &nbsp;# my initial error<br>&nbsp; &nbsp; &nbsp; &nbsp;insted of using breaks or carting it all off into a<br>&nbsp; &nbsp; &nbsp; &nbsp;sub where I can use 'condition or return' statements.<br><br>&nbsp; &nbsp; #2 I'd hoped for more perl code in T::S::C<br>&nbsp; &nbsp; &nbsp; &nbsp;but it's all hidden to avoid spoiling the effect.<br>&nbsp; &nbsp; &nbsp; &nbsp;Silver lining: maybe I'll start playing with source<br>&nbsp; &nbsp; &nbsp; &nbsp;filtering to figure it out myself.<br><br>&nbsp; &nbsp; #1 I could only be in one room at a time. Silver lining:<br>&nbsp; &nbsp; &nbsp; &nbsp;I'm looking forward to seeing more recorded sessions<br>&nbsp; &nbsp; &nbsp; &nbsp;show up on the web as folks get settled in and have<br>&nbsp; &nbsp; &nbsp; &nbsp;time to process their recordings.<br><br>Of course not every cloud has a silver lining...<br><br>&nbsp; &nbsp; #0 YAPC was over far too quickly<nobr> <wbr></nobr>:(<br><br>Biggest Bummer of them all:<br>&nbsp; &nbsp; I think I might have to miss YAPC next year. We'll be<br>&nbsp; &nbsp; moving to Portland, OR around YAPC season, and so not<br>&nbsp; &nbsp; only will the budget be leaner, but time will be more<br>&nbsp; &nbsp; precious (and likely spent job-hunting). Sigh...<br><br>-matt</tt> wickline 2002-07-01T21:57:40+00:00 journal