Stories
Slash Boxes
Comments
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 ]

waltman (335)

waltman
  (email not shown publicly)

Journal of waltman (335)

Monday February 23, 2009
11:34 PM

They don't write them like that anymore

Today I found myself needing a citation for the Floyd-Warshall algorithm. This is a famous algorithm in graph theory that simultaneously finds the shortest path between every pair of nodes in a weighted, directed graph. (A nice description of Floyd-Warshall is on Wikipedia).

Modern algorithms textbooks often devote entire chapters to shortest path algorithms, so I was surprised to see that the citation said it was only a page. I thought it might have been a misprint and I pulled up the original CACM article from the ACM website. Not only was Floyd's article less than a page, it was only about 1/4 of a column of a page. It was only 21 lines, including title and comments!

Floyd's article was published back in 1962, when men were men, computers filled buildings, and the CACM published an Algorithms column consisting mainly of short algorithms submitted by readers. The private sector seemed more involved in basic computer research then than they are now; there are algorithms in this issue submitted by researchers at Control Data, Burroughs, Sperry, and the US Steel Applied Research Lab. As for the code, I thought it was a Pascal-like pseudocode, but it turns out to be ALGOL-60.

Ah, the good old days...

Friday August 22, 2008
01:13 PM

Geek cleaning tip of the day

Should you ever remove the offmarket color cartridge from your inkjet printer and give it a shake to loosen up the cyan, only to have it dribble drops of magenta and yellow all over your laptop keyboard, spray a little Windex on a paper towel and use that to clean up the mess.
Tuesday August 05, 2008
08:38 PM

Selecting reserved word columns in SQLite

This week I've been accessing an SQLite database created by a Ruby on Rails app written by one of my labmates. It turned out that one of the tables had a column named "order", and another had a column named "group". These were perfectly reasonable names based on the data; however, they're also reserved words in SQL, which makes them tricky to access.

The trick is to wrap the bad column names in double quotes. In other words, instead of using

SELECT foo, bar, order FROM baz;

which returns an error, use

SELECT foo, bar, "order" FROM baz;

In fact, looking through the schemas it appears that RoR wraps all the column names in quotes. I suppose this must be so that RoR developers can name their fields anything they want without having to worry about the underlying implementation in SQLite.

Wednesday July 30, 2008
10:45 PM

Logging back and forward buttons in Firefox

As promised, here's my extension. First, a disclaimer. Though it's unlikely with something this simple, buggy extensions can mess up your Firefox profile, including your bookmarks, cookies, plugins, preferences, and so on. If you're paranoid, see the Firefox documentation on how to create a development profile.

The first thing you need to do is create a directory for your extension. I put mine in ~/extensions/backlog. In that directory we're going to put 4 files:

  • chrome.manifest
  • install.rdf
  • content/overlay.xul
  • content/overlay.js

chrome.manifest tells Firefox where the files are for the extension. This is right out of the Mozilla documentation.

content backlog content/
overlay chrome://browser/content/browser.xul    chrome://backlog/content/overlay.xul

install.rdf tells Firefox meta information about the extension:

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">

  <Description about="urn:mozilla:install-manifest">

    <em:id>backlog@viscog.cs.drexel.edu</em:id>
    <em:name>Back Log</em:name>
    <em:version>1.0</em:version>
    <em:description>Add history log entries when hitting back button</em:description>
    <em:creator>Walt Mankowski</em:creator>

    <em:homepageURL>http://kb.mozillazine.org/Getting_started_with_extension_develop ment</em:homepageURL>

    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>3.0</em:minVersion>
        <em:maxVersion>3.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>

  </Description>

</RDF>

Most of that is boilerplate. The most important field is em:id, because that's how you'll identify it to Firefox later on. Note that it has to be in the form of an email address, though it doesn't actually have to be a valid email address. In this extension it's important that em:minVersion is set to 3.0, since I'm using a Firefox 3.0 feature to do the logging.

content/overlay.xul tells Firefox what part of the browser we want to extend. In the tutorials they do things like add "Hello, world" somewhere in the browser window. Here I want to leave the window itself alone and just add some javascript.

<?xml version="1.0"?>
<overlay id="backlog-overlay"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="overlay.js"/>

</overlay>

content/overlay.js is the javascript code that does the logging when the forward and back buttons are pressed.

window.addEventListener("load", function() { Backlog.onLoad(); }, false);

var Backlog = {
  onLoad: function() {
    // initialization code
    var appcontent = document.getElementById("appcontent");   // browser
    if (appcontent)
      appcontent.addEventListener("pageshow", Backlog.onPageShow, true);
  },

  onPageShow: function(aEvent) {
    var doc = aEvent.target; // doc is document that triggered "onPageShow" event

    // this service is Firefox's API for logging history events
    var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
                                    .getService(Components.interfaces.nsIGlobalHistory2);

    if (aEvent.persisted) // page pulled from cache, so log it
        historyService.addURI(doc.documentURIObject, false, true, null);
  }

};

When the overlay is loaded, I add a listener for the pageshow event. This event is triggered both when a new page is displayed (e.g. when clicking on a hyperlink) and when a page is pulled out of the cache via the forward or back buttons. When the event occurs, I check the persisted flag. This is set to true when the page is in the session history, i.e. we've already seen the page once, and now we're seeing it again with Forward or Back. Firefox normally doesn't add these pages again to its history database, but that's exactly what I wrote this extension to do. To write the URI out history, I call addURI() in the nsIGlobalHistory2 service.

It's possible to package up extensions so that they install automatically, but since I only need this to run on a single box I didn't bother. Instead I just followed the instructions for testing extensions. It turns out that while extensions themselves contain lots of ugly XML and javascript code, testing them is really easy. Just go to your Firefox profile directory. (On my box it's ~/.mozilla/firefox/.default.) Then go one level deeper to the extensions directory. In that directory, create a file whose name is the id of the extension ("backlog@viscog.cs.drexel.edu" in this case). The file should contain a single line containing thee root path of the extension ("~/extensions/backlog"). Finally restart Firefox, and you should see a message saying that it's found a new extension. If you decide to disable the extension, just remove the file from the extensions directory and restart Firefox.

12:11 AM

My first Firefox extension

I've done a lot of unexpected things in grad school, but I never thought I'd find myself writing Firefox extensions. But we're doing some experiments in finding patterns in web browsing, and I needed to add an entry to the Firefox history database when the user hits the back button. Firefox doesn't normally do this, but a developer hanging out on #firefox assured me it was possible.

It turned out to be only about 10 lines of javascript, but of course coming up with the right 10 lines of javascript, and figuring out how to package them into an extension, took all day.

I'll try to post more details once I get a chance to clean out all my debugging code and hopefully make a more minimal version than what I have.

Monday July 07, 2008
01:40 PM

Fun with elisp

Recently my emacs configuration on my iMac at the lab got messed up and was refusing to automatically use cperl-mode when editing perl files. Today I finally got get up and decided to see if I could fix it. The solution turned out to be adding the following line to my .emacs file:

(defun compilation-build-compilation-error-regexp-alist() (lambda()))

It's so obvious I don't know why it took me so long to figure it out. :)

Tuesday July 19, 2005
05:29 PM

Kids nowadays

This afternoon my labmates asked me to settle an argument. They handed me some headphones and asked me who was singing. I put them on and heard what sounded like Aerosmith doing Dream On. I listened for a bit to make sure it really was Aerosmith, then ventured "umm...Steve Tyler?"

"How did you know that?" asked the woman who just lost the bet. "It doesn't sound anything like him!"

"Are you kidding? It's one of the most popular rock songs in history. I thought everyone knew that was Aerosmith."

"I didn't recognize it at all. You mean you've really heard it before?"

"Only about 1000 times." All before you were born!

Kids nowadays, with their hip hop and their iPods, I tell ya...

Monday June 20, 2005
04:10 PM

Manu, The Shadow Dextrous Hand of Fate!

Thursday June 09, 2005
04:02 PM

Harps are for angels

Heard on IRC this morning...

Someone on Drexel's ethernet has an iTunes share called (roughly) "Harps are for angels, God plays guitar"and it's full of nothing but Joe Satriani tunes.

Friday May 13, 2005
09:43 PM

Blessed are the Cheesemakers

"That's it Gromit cheeeeese We'll go somewhere where there's cheese!"