WideFinder in Io: it’s now too late

A Swede made the first WideFinder implementation in Io: Ragnar Dahlén.

The results were informative, but not performant. Io can not compete just there, just yet.

Me and Thorbiörn were conspiring last week to implement WideFinder, but we got waylaid by… distractions. The distractions were speculative, lazy, and touched on different OCamls. Like this: “We need an OCaml-shaped project. To help us learn.”

The usual get-started project is “Make an HTTP server than can 200 and 404. At least.” Hardly qualifies as OCaml-shaped…

Malmo Linux User Group Wednesday pizza meetup notes

I attended a local geek meetup at La Trattoria, at 18:30 this past Wednesday. (map)

I can recommend the mozzarella add-on to any pizza.

InterSystems Caché® got hard slammed at the meeting. Horrible war stories about that object-oriented database. The guy who told them, Micke, was also a Högskolan i Skövde alumnus.

New visitor record, says Magnus.

This morning, I ordered Peter Seibel‘s Practical Common Lisp as a paper book. Turns out, there is a Google Video with him, from 2006.

Hack-a-thon, in my town!

More groups of people who want to fiddle with opensource software: Hackaton.se. They have an event in Malmö, at a school, 23-25 november.

Just to let you know, so you can spread the word. I’ll write more when I know more.

Update! An attentive reader, also being the organizer of the upcoming event emailed me, and told me more. It’s called “Hack-a-ton”, note the Scandinavian spelling. URL changed to reflect this.

Web hacking Øresund, a local computer get-together

Folks, I live in Malmö, Sweden. Update: Web Hacking Oresund web page.

And I like hanging out, making stuff. So, I set up a Facebook group called “Web Hacking Øresund”. (yeah, yeah, silo-of-content, and all, I’ll go and set up an Upcoming Event for it, instead).

The concept: meet up, checking out the stuff you’ve saved up to check out. Do stuff.

Last time, which was the first, we looked at C64 conversions of PC demos. Wild stuff. Processing, the graphics programming environment (basically NodeBox for Java) was installed and fiddled with. Some Web stuff was demoed, but our focus was on getting to know each other, make our interests known. A Clubbe, simply.

We later adjourned the meeting for a quiet pilsner in a nearby café.

Things went well, plans were hatched. Next meetup will be about starting stuff, possibly getting to know more about text-mining. Or math. Or Apache projects. Or ExtJs. Or something else.

Crosscheck wheel spin

At the last meeting with Copenhagen.rb, I said I’d test out Crosscheck – a JavaScript testing framework, suited for continuous integration or command-line testing.

I had just tried getting it to run, following the slightly outdated Add Event tutorial. At last I got it to work, but I had to actually read the text, not just paste the examples. Better grab the example source code than read the slightly-outdated docs.

Tonight I have tested it in a little more real setting: I had a hunch of how I would be able to do a filtering function that worked like in Quicksilver or Textmate. A case-insensitive, very inclusive search that just narrows down based on the sequence of the characters, not on their immediate order. (Did that make sense?)

Expressed as a positive test case: “jy8” should match “Jyri is happy to be 8 years of age”.

Anyway, I thought I could construct a regex on the fly, somehow. I itched to try. And I wanted to try it using tests along the way.

So, I entered the first, simplest case I could think of: equality. A list of one element should return only a single-element array. That was simple to do, so I could take on the next (that I could think of). And the rest was just implementation, until I hit something I had to test in Firebug.

The cool thing was that my experimentation was over as soon as I’d answered the question I had. Focus, the programmer’s holy grail. The promise of focus, at least. We’ll see about how that holds up in practice.

Here is the quite redundant, stupid list of test cases that I accumulated while trying things on:


crosscheck.onSetup(function(){
    crosscheck.load("scripts/quicksilverSearch.js");
});
crosscheck.addTest({
    testShouldFindSameMatchingString : function () {
        var outPut = quicksilverMatch('johnny', ['johnny']);
        var exp = ['johnny'];
        assertEquals( exp[0], outPut[0], 
            'The same word could not be found in the simple array. Shame.' );
    },
    testShouldNotFindANonMatchingString : function () {
        var outPut = quicksilverMatch('jx', ['johnny']);
        assertTrue( outPut.length == 0, 'The word jx was found in johnny?! Shame.' );
    },
    testShouldMatchAllOnFirstLetter : function() {
        var outPut = quicksilverMatch('jo', ['johnny', 'jools', 'june']);
        assertTrue( outPut.length == 2, 
            'Unable to match with indexOf on the first two letters. Shame.' );
    },
    testShouldMatchAcrossWords : function() {
        var outPut = quicksilverMatch('jy', ['jyri', 'johnny', 'june']);
        assertTrue( outPut.length == 2, 
            'Unable to match across words. Shame.' );
    },
    testShouldMatchAcrossWordsCaseInsensitively : function() {
        var outPut = quicksilverMatch('jy8', ['Jyri 8 years', 'Johnny turns 8', 'june']);
        assertTrue( outPut.length == 2, 
            'Unable to match case-ins. across words. Shame.' );
    }    
});

So, the first thing that gets done before execution of each test case: load my script. That is specified in crosscheck.onSetup.

The least interesting part of this is my resulting code. After pulling it through JSLint and mulling over it a couple more times, it just shrunk. Which is the end goal of testing, I guess: to have me own as little code as possible. (We’ll come back to that.)


/**
 * "Quicksilver" filter search: returns an array of the haystack elements that 
 * match case-insensitively the given term.
 * 2007-10-05, Olle
 */
function quicksilverMatch(term, haystack) {
    var matches = [];
    var straw; // The individual piece of hay
    // "t.*e.*r.*m" regular expression for loose matching
    var re = new RegExp(term.split("").join('.*'), "i");    
    for (var idx = 0, len = haystack.length; idx < len; ++idx) {
        straw = haystack[idx];
        // Direct match inside word? Or: a case-ins. loose match
        if (straw.indexOf(term) > -1 || re.test(straw)) {
            matches.push(straw);
        }
    }
    return matches;
}

The take-home piece I got from this sitting was how to run Crosscheck. I created a wrapper shell script that I christened “crosschecka”, where I set my target browsers (“hosts”) and paths:


#!/bin/bash
#
# Run the crosscheck jar on given test path, or default
#
# We run on Firefox 1.5 and IE6: moz-1.8:ie-6
# 
# Author: olle, 2007-09-26

CROSSCHECK_JAR=/Users/olle/lib/crosscheck-0.2.1/crosscheck.jar
# Colon-separated. Possible values are moz-1.7:moz-1.8:ie-6
HOSTS_TO_CHECK=moz-1.8:ie-6    

# Our test path is tests/eosweb/js, relative to the web app root
if [[ $1 == '' ]]; then
{
    java -jar $CROSSCHECK_JAR -hosts=$HOSTS_TO_CHECK tests/eosweb/js
    exit 0;
}
else
{
    java -jar $CROSSCHECK_JAR -hosts=$HOSTS_TO_CHECK $1
    exit 0;    
}
fi

(I never got the file test in the else clause right, so I let Crosscheck complain for me.) The Rails-type win here is having a pre-set default, so I never have to think about it.

Thought: Maybe this whole testing thing is a way to get me to reduce the scope of my methods? To be testable, they have to be decomposed to parts that are cheap to test.

I said I’d come back to owning less code: now that I know these things about the behaviour of my code, do you think I should revisit and sharpen up my test-cases? For one thing, some of them might not even hit right. The first one, it seems very weak and situationally dependent.

Would you go back and change such stuff? Or delete such cases?

Copenhagen.rb: September meetup, minor review and or notes

Last night, a Ruby club meet, which was interesting, but the feeling I got was “you hadda have been at RailsConf”. And I wasn’t, so bummer.

Informal atmosphere allows one to play with one’s laptop while others are reminiscing:

ActiveWarehouse a data warehousing application. Could be very interesting. Funny: me and Isak had said “Let’s analyze our SVN logs, that a nice chunky dataset.” He showed his first steps, grabbing the XML output Subversion can report about its logs. They were rich enough to map to… a data warehouse.

And, as it ironically turns out, the seminal example for ActiveWarehouse is activewarehouse-example-with-rails-svn-logs. Going to play with this, when I get some time.

When I was not listening, I was struggling to get offline browser tests running with Crosscheck, which packages up IE6 and Firefox (1.5 and the older 1.0):

It’s just a JAR, so you run it on a folder with tests:

java -jar ~/Desktop/crosscheck-0.2.1.tar/crosscheck.jar \\
-hosts=moz-1.8:ie-6 \\
tests/eosweb/js/

I want to hook this into our Bitten installation.

Super-secret note, only for you: I also made a note about the Oresund Web Hacking club, which only exists on Facebook (as a local group), so befriend me there, or search for the above name. Something more public will get created.

A locksmith hint from Malmö

Life hint: Do not insert the wrong key in the lock, you could fiddle the tumblers of the lock, so that the lock no longer fits your key.

Life hint for Swedes: hitta.se search for “lÃ¥ssmed” and a location like “Malmö,” and you can also see the many locksmiths near my home. Abba LÃ¥s-specialisten was first in the list, and had a cellphone listing. Good. Cross-referencing this info with another search gave that this was their “on-call” number.

Interesting to see companies that do not need websites. A polite voice in a phone was more than enough.

Another Ruby conference

The Ruby folks in Texas know how to please a soft-heart like me:

This is a non-profit conference. The organizers are not paid and any profits will be used
for future conferences.

Also, the financial books are open and we will be publishing payables and receivables.
The purpose of this is to help other conference planners and to assure attendees that their money is well spent.

Very impressive, and great. Messrs Jim Freeze and David Bluestein II and Damon Clinkscales – big up from the Oresund Ruby massive.

Also: The format of a “pre-conference conference”, where the attendance fee is a donation to a charity, is a neat pattern that more and more conferences follow.

Powered by ScribeFire.