Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

rjray (1649)

  (email not shown publicly)
AOL IM: rjrayperl (Add Buddy, Send Message)
Yahoo! ID: rjray_perl (Add User, Send Message)

Journal of rjray (1649)

Thursday January 31, 2008
05:18 PM

The Secret of My Success has been very good to me over the years. Two of my last three permanent positions (this one happened to come from a headhunter approaching me via LinkedIn) came from there. In addition, I've gotten three short-term contracts as well. And I've always assumed it was because I was eminently qualified for the positions I aimed for. Now, I know otherwise.

My company is looking for another Perl programmer, one with strong MySQL as well. The CEO asked me to call upon my vast connections in the Perl community (*snerk*) to see if I could bring in a better calibre of candidate than what we had been getting from headhunters (present company excluded, I suppose). So my first impulse was to post the position to j.p.o. Heck, I even convinced the CEO to whip out a credit card and pay for front-page placement.

I've gotten three replies. One was from a recruiter wanting to send us a resume in exchange for a promise of a fee if we hired the person. One was from a person living in India who clearly missed the "on-site" part of the listing. But the one who really amazed was the person who replied "saw your job posting on craigslist" (no, you didn't), didn't provide a resume (even after I asked for it in three separate email messages), asked what the projected total hours were (missing the "full-time" part of the ad) and whether he could telecommute (at least the fellow from India only overlooked this one detail, and had provided a resume). It now looks as though my luck with the jobs site can be boiled down to the simple fact that I can read and follow instructions.

Perhaps this is just a corollary of what I warned the CEO initially: all the Perl programmers I know who are good, already have jobs. They are rarely unemployed for any period longer than they choose to be. And unfortunately for me, none are (currently) looking for work.

Friday September 21, 2007
05:46 PM


I have a (reasonably stable) Twitter-bot up and running. Like the existing "cpan" Twitter, it spools CPAN uploads to Twitter from the RDF that publishes. Unlike "cpan" (which was apparently shut-off a little over a month ago anyway), it provides links: The released package itself is linked, and behind the scenes the MANIFEST file is scanned for something matching /(changes|changelog|changelist)\b/i and if found is also linked. If no change-file is found, README is linked to instead (unless there's no README, in which case you just get the one link instead of two).

The bot polls the RDF URL every 15min or so, using an If-Modified-Since header. Any new CPAN uploads are queued up for posting to Twitter, spaced out evenly over the 15min waiting period (i.e., if there are two new CPAN uploads then tweet fires immediately and the second waits roughly 7.5 minutes to fire... fifteen new uploads would fire at roughly one-minute intervals) so that it doesn't suddenly spam your Twitter client.

This is still largely alpha, though the code itself is reasonably clean (one must love being borderline-OCD). I want to add better local logging, reading of direct messages to interpret them as commands, stats tracking, etc. to it yet. Also, I plan to abstract the overall architecture moreso than it currently is, and CPAN that as a Twitterbot sort of class/mini-framework. For that matter, the structure of the message that gets sent as a tweet is itself vulnerable to change yet, as I'm not 100% happy with it (but as far as I know, I can't use HTML for formatting, so I can't (for example) link the module name to the CPAN page, I can only send the URL in the message body and rely on clients like IM or Twitterific to hot-link the text).

For now, though, you can get your CPAN addiction fed via Twitter at:

(I'm also thinking about changing the name to "cpan_with_links". Alternately, if the current owner of the "cpan" Twitter account wants to talk, feel free to e-mail me.)

Friday March 30, 2007
05:05 PM

The Potential Ending of a Long Relationship

It may be over, this, one of my longest relationships. For nearly 20 years we've been faithful partners, ever since I was first introduced my sophomore year of college. No, I don't mean Perl, because this pre-dates my love of even Perl by several years. No, I fear my relationship with (X)Emacs may be coming to an end.

It was so wonderful at first, that rush of New Relationship Energy. I was introduced to emacs by a few older CS students I'd befriended, one of whom had left MIT to return to Oklahoma because the student loans were starting to scare him. OU didn't teach Lisp (or Scheme), so he channeled his fondness for these into emacs and emacs evangelism. I was teased mercilessly for my simplistic use of vi, and repeatedly tempted by emacs' many and varied features. Programmability not the least of them. Mind you, we didn't have vim then. Heck, elvis hadn't even entered the building, let alone had time leave. So I was lured in by the promise of excitement and exploration emacs offered.

For years, I've faithfully used emacs, then XEmacs. I've watched my customizations grow from one meager e-lisp file to a set of six files (not counting the master ~/.xemacs/init.el file and the generated files like ~/.xemacs/custom.el). Plus literally dozens of other files I've collected, some of which eventually ended up in the core distribution (like cperl-mode). Possibly my favorite of the small and subtle additions would have to be the bindings for <Home> and <End>:

(defun home ()
  "Home - begin of line, once more - screen, once more - buffer."
  (interactive nil)
    ((and (eq last-command 'home) (eq last-last-command 'home))
     (goto-char (point-min)))
    ((eq last-command 'home)
     (move-to-window-line 0))
    (t (beginning-of-line)))
  (setq last-last-command last-command)

(defun end ()
  "End - end of line, once more - screen, once more - buffer."
  (interactive nil)
    ((and (eq last-command 'end) (eq last-last-command 'end))
     (goto-char (point-max))
    ((eq last-command 'end)
     (move-to-window-line -1)
  (setq last-last-command last-command)

They aren't mine, but I happily added them. With these, <Home> will go to the start of a line on the first press, to the top left corner of the buffer on the second, and to the very start of the file on the third. Very handy, much less RSI-worthy than ESC-<. And <End> does the same thing, only going end-of-line, bottom-right-corner, end-of-buffer. The thing is, I have literally dozens of these, if not into the hundreds, that I've accumulated over the past 20 years. Some I've written, most I've gotten from newsgroups and the like, as people shared their favorite little hacks.

But I've grown, matured, and XEmacs has been slow to keep up with the world around us. Even with the MULE package installed, I have a headache trying to type in Cyrillic in a buffer. And when I save it, it usually mangles it. I try to set the encoding for the buffer, but while it has nearly 100 encodings to offer me, none of them are UTF-8. The GUI is clumsy, even in XEmacs which forked from emacs specifically to address GUI issues that the emacs base was not interested in dealing with. Handling of fonts is just plain retarded, refusing to set a face to certain size values even when I know that the font itself is TrueType, and is coming from the Xorg font server as available in pretty much any size you ask for. Even the GTK+ port fails me... it's in worse shape than the older one. It's linked directly to the GTK+ environment (and thus their improved font handling), and the interface is still retarded, especially in the handling of fonts.

Granted, for such a sizeable application XEmacs' memory footprint is pretty small. But when I look at the other tools available to me-- jEdit, Eclipse-- it just can't keep up. Mixed-mode editing? Only as a clumsy hack. Integration with your desktop? Not even remotely. Sure, Eclipse is a bloated, monolithic IDE, but I can easily switch to something lighter-weight and have the same basic key-bindings when I have smaller tasks.

Though it pains me to turn my back on 20 years of friendship, I just don't know how much more time I can waste trying to work around these things. The cases where I have to go to an alternative editor just because XEmacs can't handle the file in question grow almost daily. I think it may be time to put XEmacs on the shelf, alongside the class ring, fraternity jersey and other relics of my college days.

Sunday March 11, 2007
03:11 PM

This Will Be The Next Book I Buy

But don't we always need more books?

Either way, I'm getting this noble tome as soon as I can. One thing I take some degree of pride in, is the readability and cleanliness of my code. Being mildly OCD probably has helped over the years, but I'm positive I can learn something from this book.

More on the title, with a chapter listing, here.

Monday October 30, 2006
04:04 AM

My First Catalyst Bits

I've put up the second release of my first foray into writing add-ons for Catalyst: Catalyst::Model::ISBNDB. It uses my WebService::ISBNDB (now at version 0.31) module to provide access to the web service as a Catalyst model.

This release adds a component to work with Catalyst::Helper, so that one can use the * script that generates for you, to auto-create a model component for your app that derives from Catalyst::Model::ISBNDB. Since the version number on the main class didn't change, this change won't appear in CPAN for anyone who'd actually installed C::M::I.

Wednesday September 27, 2006
01:33 AM

Tie-Magic and Inside-Out Objects

Anyone rolled these two together? Experiences, positive or otherwise?

For my WebService::ISBNDB package, I'm working on implementing a HOP-style iterator to return when the user does a search. Some searches, especially when vague, could return well into the hundreds (if not thousands) of matches. Add to that the fact that the service only returns data in pages of 10, and an iterator that hides all this hassle from the user makes sense.

What also makes sense, though, is expecting something like that sort of search to return an array, or at least an array reference; one that can be manipulated with pop, shift, etc. Even push and unshift, though in this case I would imagine one might not want to allow adding to such an array (you can always copy what you want to a separate array and add in whatever else you need).

Enter tied arrays. The TIEARRAY method doesn't have to return an array reference. Even the perltie man-page uses a hash-reference for the examples under "Tying Arrays".

Enter, from the other side of the stage, that new darling of the Perl OO community, the inside-out object. Which I've enjoyed working with in this very project. So why not try getting some of that peanut butter in my chocolate? Obviously TIEARRAY can return an IOO. And when you call tie, it has an actual return value, the referent that TIEARRAY returns (or TIESCALAR, TIEHASH, etc. as apropos). You could (conceivably) then choose to use the core object with methods like next, first or all. Or you could use the tied array, with the usual array-related operations.

Of course, there would be issues whether or not you wanted the "array" to be mutable via slicing operations, what to do if the user addresses both the iterator and array interfaces, etc. But it gets me to thinking, and that often comes of no good...

Sunday September 24, 2006
10:42 PM

WebService-ISBNDB 0.20 Uploaded to CPAN

I've just uploaded the second "real" release of WebService-ISBNDB, version 0.20, to CPAN. I don't have the thing working that I used to, because I don't use fetchmail anymore (I leave stuff on my IMAP store or save it to a Thunderbird folder). That means I never announced the first release, or the two previous releases that were named Net-ISBNDB. I changed the name after Adam Kennedy made a good argument for the WebService:: prefix.

This package is an object-oriented layer over the actual published API of It presents all five elements (authors, books, categories, publishers and subjects) as classes. Elements that reference other elements (such as the authors, subjects and publisher of a book) are lazy-loaded when first requested through the accessor methods. You'll have to have an API key from them, which is free once you've registered. The catch is that the key is generally good for 500 requests per day, which most of you probably won't find to be an issue. It did become an issue for me, though, when writing the test suite that this release introduces (the first release had some basic tests, but no actual data tests). I quickly ran up 500 requests in less than two hours the other day. As part of addressing this problem, I checked and found that my suite of tests was making 58 requests per complete run. I had created a key that I was going to use for CPAN build/install runs, but it was clear that the key wouldn't work very well; more than eight people installing in a given 24-hour period would tap it out.

Solving the problem actually proved the robustness of the base communication class, WebService::ISBNDB::Agent (points to the version from the previous release). I was able to create a dummy adapter, overload just one method, and BAM! it would read the XML from local files in the test-suite directory. Even better, I was able to make a run of the suites that actually read from the service, and save all the requests to files, by having the dummy adapter go ahead and call the super-class method and write the data to the filename it would have otherwise read. I then restored the method to the read-data approach, and my hits on the service dropped from 58 to 0.

This was also my first foray into using Class::Std . As someone who worries (too much) about people sub-classing my classes and stepping on my keys, this is an interesting approach. I had some weird issues to work around, though. The framework is meant for you to not have to (ever) write your own new(). So if you do, you have the issues. I had assumed that I could just use Class::Std as my class' base, and it works, but it doesn't seem to be intended for that purpose, at least not on the surface. And in my case, I wanted to provide some syntactic sugar for object creation (i.e., if you are instantiating an object from a known-to-be unique value, you should be able to do so with minimal typing; something like "$book = WebService::ISBNDB::API::Books->new($isbn)"). To make the sugar work, I had to allow new() to take something other than a single hash-ref. And to do that, I had to provide my own. When I did, I got warnings about redefining it, since Class::Std generates one when you use it. I'm not sure how I'd recommend getting around this... I suppose Class::Std could check that you both have an existing new() and have Class::Std in your inheritance hierarchy.

The other issue I had to struggle with is that I'm currently very busy with paying work right now. And every hour I squirreled away for this felt like I was stealing it from "more important" work. The amount of change this release delivers kind of defies the ten days or so since the last release. I could have done all of this in a day (maybe two if it was the weekend and I had other distractions). But I've been sick all of this past week, and I've felt kind of bad each time I worked on this instead of the other. Obviously not too bad, I guess, or I wouldn't be releasing a new version.

This is also the first NEW module I've come up with in what feels like ages, so I'm pretty happy with myself to have broken out of my rut. Now if you don't mind, I have some more hacking (of the phlegmy-lung-variety) and wheezing to attend to.

Friday June 30, 2006
03:12 AM

RPC::XML 0.59 Uploaded to CPAN

I've just uploaded version 0.59 of RPC::XML to CPAN. It's been over a year since the last release(!) and I've made a number of small changes, many of them to test suites so as to have a little better coverage. Some of those (pod testing and pod-coverage testing) let to fixes in other areas. I have to say that the CPANTS site has proven very helpful to me, by laying out what problems my distributions have. Where the actual CPAN-testing cadre will let me know if my module has build-level or test problems on platforms, CPANTS shows me what can be improved in the distribution itself.

Nicely done, guys.

Thursday January 05, 2006
04:51 PM

Clearly I Fail to Grasp Bayesian Anti-Spam Filtering

I say this, because I would expect that after flagging 50+ copies of the "Remington Ventures" virus-spam, Thunderbird would finally be catching them on my behalf.

Maybe the message is long-enough to water down the effectiveness of the tell-tale tokens. But I count three or four tokens that I'm pretty sure only appear in these messages.

Thursday September 22, 2005
04:02 AM

Subversion vs. Scatterbrain-ness

I've been very interested in switching to Subversion for some time now. More to the point, I've been looking hard at SVK, especially after recently reading this three-part article. I remember having a long talk with Dr. Walter Tichy, the creator of RCS, back in 1995 at the International Conference on Software Engineering. I had just presented my first-ever published paper, and he had been in the SCM workshop that it was featured in. What I wanted him to do, that he had thus far opposed, was to allow developers to re-engineer RCS as an embeddable library, like Zlib. I wanted a componentized version-control system that languages like Perl could create bindings for. He wouldn't, though. He was working with a company to make a souped-up RCS that was going to have that feature, and he didn't want a free system competing. Of course, CVS has now long-since given up on wrapping RCS and does everything internally. But better yet, we got Subversion instead of a dressed-up RCS.

Well, there is one thing that still keeps me from switching. A habit I developed, that I suppose now counts as a bad habit. And I'm pretty heavily-invested in it at this stage. It's a trick I picked up from Tim Bunce in his DBI module. I know others use it, too, and I'm hoping that someone has already faced down this spectre, and can offer me some advice.

I let CVS set the $VERSION variables for my CPAN modules.

I do it with this little snippet, variations of which must surely be all over the open source universe, not just CPAN:

$VERSION = do { my @r=(q$Revision: 1.35 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r  };

Without that, I have to not only go back and manually set all those $VERSIONs, I have to also start remembering to adjust them each time I am planning a new commit for a given Perl module. And I'm absent-minded. My CVS histories are littered with Makefile.PL check-ins where I forgot bump the package version before starting to build a new CPAN release. And I know that Subversion has keyword expansion similar to CVS. But their handling of versions is vastly different. If I commit three files, each of those three will have the same version number at their "head". If I have the keyward in place (and expansion enabled), those files will all get that number, which is an ordinary integer, not a dotted-pair or -quad. Right now, if I don't change, say, RPC::XML::Parser for 4 or 5 releases of my RPC-XML package, it just stays at the version it is. But, if I understand Subversion correctly, when I make a clean check-out of a tag in order to build it for CPAN release, the version keywords would all have the same value. And since SVK is based on Subversion, I'm presuming the same issue is going to be present there, as well.

So, this is what I need to solve before I can start moving my code to SVK, or really even consider starting new projects with SVK/Subversion at all.