Archive for September, 2004

Perlthon

I’ve been writing alot more Perl at work lately, which suits me fine. With my Perl still a bit rusty, however, I found myself dashing off lots of -e one-liners to test various bits. After a while, I wanted a quicker way to test things…an interactive mode such as Visual Basic’s immediate window or Python’s interactive mode.

Perl being perl, this sort of thing is crazy easy. As most perl programmers know, or can quickly figure out, the fastest way to get an interactive perl session is: perl -ne eval;

which will eval every line of input until input ends (CTRL+D on *nix systems) or you type exit (as exit is a perl builtin which does just that). This command has no explicit output, you’ll need to include your own print calls to see output. Still… quick, dirty, and handy. A slight tweak if you’ll be printing most everything you feed it: perl -ne ‘print eval; print “\n”‘

This autoprints everything. Note the use of two print statements; this is on purpose. If instead we use print eval() . "\n", the eval will be called in scalar context. Try printing localtime, if you see a nicely formated date, scalar context is to blame. If you want such a thing, just print scalar localtime. Best of both worlds. The other choice for combining print statements is print eval, "\n". This calls eval in list context, however, it also passes "\n" to print as part of the list. This means that using: $,=”,”; localtime;

to print the localtime array with commas will add a comma to the end of the line as well (before the "\n").

Never content to leave well enough alone, however, I wanted more. Command history and in-line editing. Multi-line command entry (a la Python). A help function. A quit function that doesn’t (a la Python). You know, toys. The result is Perlthon, an interactive Perl session that works like Python’s interactive mode. It’s easier to show than to tell, so here’s a sample session:

$> perlthon
Perlthon running Perl 5.8.0
Type "help;" for help, "exit;" or press CTRL+D to exit
>>> help;
Perlthon, the Interactive Perl Interpeter v0.1
by Jason Clark  <jason@jclark.org>
This is Free Software.

Enter commands for perl to evaluate, a la interactive Python.
Lines without a ; are continued on next input.
By default, the result of each evauation is printed.  To disable, 
use this: "$AUTOPRINT=0;"

Use "exit;" or CTRL+D to exit.

Prompts are controlled by $PROMPT1 and $PROMPT2, which you can change.

>>> localtime;
59371729810432721
>>> $, = ",";
,
>>> localtime;
10,38,17,29,8,104,3,272,1
>>> scalar(
...    localtime
... );
Wed Sep 29 17:38:30 2004
>>> quit;
Use "exit;" or CTRL+D to exit.
1
>>> exit;
$>

Bugs: Oh, you betcha. Weird behavior when Term::Readline has to fake it and you’ve changed $,. Also, because Perlthon looks for ; at the end of line to know when it’s time to eval, entering a multiline sub is a pain. You can beat it by ending each line with a comment (#). Of course, this could be considered another bug… semi-coloned lines ending with comments don’t run unless the comment ends with a semicolon. I’d like to have a block mode (if inside {} then ; doesn’t end multiline input), but this is trickier than it looks. Consider: do { #comment with a } foo; }

But hey, works for now.

The Thing about Themes

When I first got my Mac, I used IE as my browser. A short time later, Safari was released, a I discovered tabbed browsing. I loved Safari, and loathed going back to IE when at work (Windows). I was happy.

Then I decided to start my own website (you’re soaking in it). My hosting company’s web-based site admin panel didn’t work correctly in Safari or IE/Mac. They suggested Firebird (formerly Pheonix, and soon to be Firefox). I resisted, but eventually tried it. A week later it was my primary browser – at version 0.6.1. This was due in very large part to Firefox’s cross-platform nature. Using a Mac at home and a Windows PC at work, I value any useful app which looks and feels the same in both locations (probably why I’m using emacs much more these days).

Then something happened- version 0.8. The Mac version got a new default theme, to make it more Mac-like. While I applaud the sentiment, what it really did is make it less Firefox-like. With a different theme on Windows and OS X, my seamless cross-browser experience had suddenly grown some huge, ugly seams. I was never very successful finding an independant theme I really liked, but eventually I settled on Qute by Arvid Axelsson. This was the default windows theme, and was also available for the Mac. I got to really like Qute.

Then something else happened- version 0.9. Gone were Pinstripe on Mac and Qute on Windows; we got a new, standard theme. Good plan, although I missed Qute, and I couldn’t install it- it didn’t work with the OS X version of 0.9. Since both platforms were the same, I eventually got used to the change, and all was good. (Note: At least I think so. Until today, I would have sworn that the Mac and Win versions of 0.9 had identical default themes. Tried running an old copy of 0.9 today on my Mac, and the default theme matched the OS X 1.0PR default theme. Don’t know if this is a profile thing, or If i just never noticed the difference).

Then something else happened – 1.0 Preview Release. I noticed a difference on the Mac when I installed the new version (At least i think so, see prior paragraph). The Win and Mac default themes are similar, but different enough to really bug me. I prefer the Windows default theme. Also, Piro’s TabBrowser Extensions made weird looking tabs under the default Mac theme. Changing themes fixed that (I tried pinball for a while). Of course, you can’t download the Windows default theme (or any default) from the update website. Today, I finally got tired of the issue, and tried to overcome the problem. I copied classic.jar from the chrome folder of my windows install, and used it to replace the version in my OS X install. It’s almost perfect. The only problem is the scroll bars… they don’t appear. There’s room for them, and If I click in the right place, they function, they just aren’t displayed. I’ve seen this with certain themes in older releases (I think Qute used to do it), and the current Qute release does the same thing. For now, I’m dealing with it, but eventually, I need to see if I can edit the theme and fix it.

I really hope that when the final 1.0 gold release of Firefox is released, all platforms will share a single, identical default theme. Firefox is one of the best cross-platform apps I’ve ever seen. It should look that way.

Feed Autodiscovery

Among the new features in Firefox 1.0 Preview Release is Live Bookmarks, which lets you view an RSS or Atom feed as a bookmark folder. Firefox takes advantage of RSS Autodiscovery to determine the availability of a feed for your page. Implementing autodiscovery is a cinch, just add an extra <link> to you page’s head. For an RSS feed:

<link rel="alternate" type="application/rss+xml" title="RSS"
      href="http://www.example.com/yourrssfilename.xml" >

And for an Atom feed:

<link rel="alternate" type="application/atom+xml" title="Atom"
      href="http://www.example.com/youratomfilename.xml" >

When a feed is present, a little orange XML icon will appear in your status bar; clicking the icon allows you to add a Live Bookmark. Personally, I’d rather be able to use it to add a Bloglines subscription, more on that in a moment.

The presence of the XML icon on the status bar can be instructive. For example, while viewing the Newest Firefox Extentions page on Mozilla Update, the XML icon appeared. Searching the page, I could find no link to the feed. This feed seems to be autodiscoverable only. By using view source, I was finally able to subscribe to feed (see blogroll for link, category Techish).

The absence of the XML icon can also be instructive. Turns out I never added an autodiscovery link to my site. Shame on me. I’ve added the link, if you’re using Firefox 1.0PR (or newer), you should see the XML icon in your status bar. For now, every page contains an autodiscovery link for the main RSS feed. However, Blosxom provides RSS feeds for all categories as well (RSS is just another flavour to Blosxom). I could have category indexes provide autodiscovery links to category RSS feeds, but I doubt this is what most users would want.

Nice as the feature is, Live Bookmarks are no replacement for a good aggregator – Bloglines is my pick. I had given some thought to developing an extention to change the behavior of the icon (I’ve been meaning to learn how to write extentions for a while), but now I don’t have to. Michael Koziarski has released version 0.7 of Feed Your Reader, a Firefox extension. Originally designed to support desktop aggregators using the feed:// scheme, the new version adds support for many web-based aggregators, including Bloglines. I’ve downloaded it but not yet restarted Firefox, so I haven’t given it a try, but I will soon. More later.

Developer Humor

Sometimes we get a little punchy around the office on a Friday afternoon. I came up with an idea in the middle of a debugging conversation, and had to run with it. If you’re not at least passingly familiar with C, it just isn’t funny; don’t waste your time.

user: what’s a handle?

hacker: No, *what‘s a pointer.

user: I don’t know. What is a pointer?

hacker: Yes.

user: But where is the data?

hacker: No, &where is the address. The data is there.

user: where?

hacker: The address.

user: So where’s the pointer?

hacker: No, *what‘s the pointer. &where's the address.

user: And the pointer?

hacker: *what.

user: The pointer?

hacker: *what.

user: THE POINTER?

hacker: *what!

user: Forget it.

hacker: No, you can’t forget(it), you need a handle for that

user: But what’s a handle?

hacker: No, *what‘s a pointer.

user: I can’t handle this anymore.

hacker. That’s because this is an object. You have to use this->handle().

user: what handle?

hacker: No, *what‘s a pointer.

user: I don’t know! I don’t understand it!

hacker: it‘s just an integer, which is why you can’t forget(it)

user: I need a handle for that?

hacker: No, that() returns a handle.

user: And what is that?

hacker: A function that returns a handle.

user: But what’s a handle?

hacker: No, *what‘s…

user: A pointer! I got it. But what does it point to?

hacker: it‘s not a pointer, it‘s an integer.

user: Fine. what’s an integer?

hacker: No, it‘s an integer. *what‘s a pointer.

user: I quit.

hacker: Be sure you return an exit code.

user: But I didn’t take one!

hacker: What are you talking about?

user: !!

With apologies to Laurel and Hardy Abbot & Costello.

Howto treat a Perl Scalar like a Filehandle

This morning, for the second time in as many weeks, I banged my head against a Perl problem I thought should be simple: I wanted to open a filehandle against a scalar (or perform some other chicanery) so that if I have a scalar $text full of text, I could do this:

while (<$fh>) {
    #do something with $_
}

Where the filehandle $fh would refer to the contents of the scalar $text. This seems like an obvious thing someone may want to do. While you could just as easily do something like foreach (split /\n/,$text) { #... }, I had a situation where I might have data in a scalar or in a file (or even STDIN) and I wanted to treat them all the same. I expected this would be covered in the Camel and/or the Cookbook, but I couldn’t find any such thing. I didn’t have much luck on the web either. In the end, I took the low road and faked it with a system call and a pipe, since I the script I was working on is infrequently used. Here’s that version:

open(FH, qq[echo "$text" |]) or die "Can't pipe.";
while (<fh>) { #... }

When the same problem came up this morning in a web service I’m working on, I decided to try researching it again, since I really didn’t like the pipe solution. After alot of digging, I came across the perl module IO::Scalar, which lets you do exactly what I wanted. The IO:Scalar version of the code looks like this:

use IO::Scalar;
my $fh = new IO::Scalar \$text;
while (<$fh>) { #... }

My test app worked nicely on the Unix development server, but then I realized I still had a problem. For some period of time, this webservice will be running on a Windows2000 web server (don’t ask). IO::Scalar is not part of the standard Perl distro. I’m using ActiveState’s ActivePerl, which makes installing Modules via perl -MCPAN -e shell, well, challenging. ActiveState has a nice Perl Package Manager; unfortunately I could find no ready-made package for IO::Scalar, so I was stuck. While stumbling around the ActiveState site looking for inspiration, I found PerlIO::scalar. Now I was on to something.

(A moment for a side note here. I would write far fewer lines of Perl code per hour if not for the fantastic Perldoc.com maintained by Carlos Ramirez. It is an absolutely indispensible resource for me. However, it’s a bit buggy. I can’t get it to let me search the perl 5.8.0 docs, and the 5.8.4 docs appear incomplete (missing standard modules). After finding the info on ActiveState’s site, I figured out how to get to it on Perldoc.com.)

According the docs for PerlIO::scalar:

PerlIO::scalar only exists to use XSLoader to load C code that provides support for treating a scalar as an “in memory” file.

The docs on the ActiveState site also note that it’s not necessary to use PerlIO::Scalar. This reduces the code to the following:

open $fh, "<", \$text;
while (<$fh>) { #... }

Excellent. Not only is it concise and easy to use, it’s part of the standard distro. I’ve documented this not only for my own future reference, but to add my bit to the world’s largest help database. I just hope I wasn’t being totally obtuse, to later find that this is Camel page 52 material.