dev

Barcamp Liverpool

I took in the first day of BarCamp Liverpool. It was Liverpool’s first, and my second, and went off well I thought. I learnt some things, saw some new and familiar stuff and felt it was time extremely well spent. It was great to see people coming out of the woodwork and talking about what they are doing.

There was much talk of iPhone apps, and the economic opportunities (or not) that presents for the developer, lots of startup hobnobbing and general feel-good about being in the industry. Something was missing though, and I’ve been trying to put my finger on it. In the evening there was a partly-for-fun “pitching” event in which people presented startup ideas to a panel. I think it was significant that the idea that got everyone most excited about was a hardware project - to monitor power consumption of a device at the socket and chart and aggregate data to build consumer awareness of energy usage and perhaps drive usage and purchase decisions. The Web2.0 narcissism is wearing thin I think - the web is maturing as a platform for real work and useful stuff to take place, but it needs more of this grounding in the practical, tangible and meaningful. I hope future barcamps and other events are able to draw more from the “fringes” of the web community, where it less about web technology and culture as a topic in itself, and more about the internet as a component in projects that touch peoples lives in tangible and practical ways.

My talk (in direct contradiction to all that) was on maturing client-side development techniques and practices, to introduce more rigour to the discipline. It was a response to the need for repeatable, reliable client-side output that is highlighted by ever more complex demands in web-based UIs. The front-end is a part of a product development process that needs just as much attention as server-side development, and as Steve Souders has being pointing out, in lot of cases, when you actual break down the experience from the user’s point of view - warrants more.

I introduced a few techniques and tools for testing and profiling client-side tech, but the topic was too big to fit in the 45 minute slot and probably left more questions than answers. I need to either break it out into complementary pieces or take a different approach to a high-level overview. My slides are posted to geekup though, and if you were there or have thoughts, please comment.

String repetition in javascript

This is about a little snippet I came up with the other month, while a colleague and I were talking about string building and its performance in javascript. I was looking for a neat way to front-pad or indent a string, and missing the

1
x
operator in perl.

It turns out there is a succinct, one-line idiom:

var indent = new Array(10).join(" ")

That gets you a 9-spaces-long string. Using the formal Array constructor (rather than the array literal

1
[ ]
) you can specify what the initial size or length of the array should be, and we leverage that when joining our otherwise empty array. The string we provide to
1
join
with ends up being repeated n-1 times. Cute huh. It also turns out to be pretty fast. Not quite as fast as the equivalent loop using += to build the string, but much faster in many cases than pushing each character into an array and joining to produce the string.

Of course if you already know something about what string you are looking to create here, its definately fastest to declare a long string like

var spacePadding = “          “;
and then
1
var indent = spacePadding.substring(indentLevel)
, and cross your fingers that spacePadding will always be long enough. That’s going to be a pain, though, when you need to output something like
»»»»level 1
»»»»»»level 2

Or, worse (or better) if you need to repeat something like

1
<span class="indent">
. Its trivial with our
1
join
trick:

var indent = new Array(indentLevel+1).join('<span class="indent">');

You can see the test file I used to time various options. new Array(n).join performs worst when n is a small number - like 20 - and its a short or single character string you are repeating. Frankly, for the use case I’ve outlined - front-padding something - that’s also a likely range. As you scale up, and start repeating 100s or 1000s of times, and also increase the length of the string you are repeating, then this margin disappears.

BarCampLeeds 08

What a day. Who knew that Leeds was this nascent tech hub. I had a hunch of course (and followed it by moving back here), but there’s enery and talent oozing out the edges here, and its surely only a matter of time before it reaches critical mass and becomes a real tech ecosystem.

What’d I learn? I started the day with an into to geocaching. Which I’d of course heard of, but somehow had lumped it in my mind with orienteering and other things which I’m not likely to ever do regularly if at all. But I’m sold - what fun, and the kids will love it - a modern day treasure hunt.


While I held onto a vain hope that I might get my demo done in time for my talk in the afternoon, I stuck around in the main hall half-listening, half working. There was the beginnings of an interesting discussion around usability and (graphic) design, but the crowd didnt really bite. I also was treated to a crash course in viral something.. marketing? self-promotion? mostly how to have a laugh on the web it seemed, and share it with as many people as possible. That I didnt quite see the point I’m sure says more about me than the speaker - who did a great job.


I missed what looked like an interesting sessison on the success of wikis, but caught a great session discussing SAAS (Software as a Service). That looks like a big slice of pie for the taking, if you can get it right.


I was introduced to the lazy web, and a clearing house kind of offering (vagueware.com) by the presenter. I was trying to remember the other site I used a while back - it was a more general (i.e. non-tech) ideas/inventions site, but its gone.


My talk was on building desktop apps with Dojo and AIR. There wasnt really enough time to dig in so I was left skimming over materials and gesturing vaguely at examples I pulled up. “Dojo” on AIR was a little arbitrary - Dojo /is/ a good fit, and does give you a real leg up when developing an html/js based AIR app. But not to the exclusion of all other libraries. Its good for the same reason Dojo is good on the web, and that there’s a couple specific affordances for AIR (e.g. dojox.storage.AirFileStorageProvider) is nice, but not in and off itself a reason to switch. The compelling case for AIR is that you dont have to re-learn anything to start developing desktop apps, and from that point of view if you’re already comfortable with javascript library, you should probably stick with it. Anyhow, I hope folks took something away from it.


Finally I caught 2 great sessions on a a more business slant. The first was tips on dealing with large organizations as a small vendor/contractor, and negotiating the beaurocratic hazards organizations of a size seem to favor. It is so easy to get burnt as these cultures crash, and it was great food for thought. And right on its heels was a discussion on preparing proposals, RFP responses. Stand-out points for me where -
ask there’s a weighting and scoring sheet for the RFP - people will often share i freely, and that will tell you what you need to know about where to spend your time in the proposal.


So I’m left with a warm fuzzy feeling about Leeds. People had travelled in - several from Manchester and one of two from London, and although actual attendance didnt quite match registration numbers, it was a respectable crowd.


I’m back for more tommorow…

doh.robot

New automated UI testing goodies just landed in dojo, and I’m moved to blog about them. Getting test coverage of the messy stuff - user interactions, mouse-movement, clicks, drags - has always been an achiles heel of testing web UIs. Any kind of automated testing is better than none (provided you are testing the right things and keeping a good testing/developing balance), but for UI testing so much can go wrong when your page/app loads up in a real browser and has a real user start poking at it you’re left with a giant hole to fill with tedious, manual testing. doh.robot (and its dojo, dijit descendants) offer the ability to write tests that include real keyboard and mouse events, that can mimic actual use of interactive widgets.

Let’s not kid ourselves - manual testing isnt going away anytime soon - and nor should it - but having a suite of tests that can catch regressions, can run though some basic load, click, move, enter input, clear input kind of interactions across key components of your app is a huge plus. It allows you some confidence to make otherwise punishing changes - that would normally require real humans to step though a test script in all your target browsers to confirm nothing got broken.

Some people may love the precarious feeling of developing without unit tests, but personally it gives me the willies. It can be paralyzing as the codebase grows and each addition and change multiplies the potential for error. When you do stop and test how much will you have to tear back when an error pops up? You dont see construction workers free-climbing as a building goes up. You build a stable scaffolding, and anchor that against each successive floor that you add. So with testing. Unit tests let you look forwards at what remains to be done, rather than worrying constantly about what you’ve already built. And with accurate, non-synthetic automated UI interaction testing that doh.robot offers, that can only be a good thing for the growth of the web as an application platform.

dijit.byNode and firebug fun

Here’s a little tip if you’re working with dojo widgets. In firebug you can select an element in the HTML view. Back in the firebug console, your selected node is available as

1
$1
So,
1
$1.tagName
shows you the element name, etc.

If you’ve got dojo on your page you can use anything dojo has provided in the console, and if you’re using dijit, you also have that stuff too. So, in the HTML view click on the element that represents your widget. It’ll have a

1
widgetId
attribute. Now, in the console, try:

dijit.byNode($1)

this is a pattern I repeat so often I actually printed and read the firebug manual to get around there with keyboard shortcuts. I recommend you do the same. Now you can quickly and intuitively explore the state of your widget:

dijit.byNode($1)._started
console.dir(dijit.byNode($1).getChildren())
dojo.getObject(dijit.byNode($1).declaredClass).prototype

And/or, you can go back and forth between console/HTML:

dojo.query("[region]", $1).filter(function(n) { return dijit.byNode(n).declaredClass.indexOf("ContentPane") > -1; });
.. gets you call the ContentPane domNodes that are descendants of your selected BorderContainer node. Click on one, and:
dijit.byNode($1).setContent("boo!"); 

its your page, have fun!

Restoring SVN repositories from disk - a story

I recently had to move off a company laptop I’d been using for a while, and (thanks to the flu) didnt have much time to do it. So, I backed up those directories I knew had any personal projects and data in and crossed-fingers I’d be able to get what I needed out of there when the time came.

One of the directories I got housed my subversion respositories (I’d been using the flat-file db option). When I started setting back up on a new laptop (and new-to-me platform in OSX) I was faced with a little problem: How to let the new install of subversion know about the old data.

A little reading around in the SVN book soon told me that what you are /supposed/ to do is run a svnadmin dump command, then create the new repos and



svnadmin load /path/to/reponame < /path/to/my/repo1.dump


Nice to know - for next time. After some searching and asking around, I finally got a pointer (from the evolt list)



svnserve –daemon –root “C:\Path\to\Subversion Repository”


That wouldnt work as-is, but it pointed me in the right direction. Subversion of course has a notion of a root directory where it expects to find everything. I was running subversion via apache though. I’d gone through the basic set up to configure it, and it was busily serving up an entirely fresh and empty repo. To cut a long story short, I finally ended up with this:



LoadModule dav_svn_module /usr/libexec/apache2/mod_dav_svn.so
<Location /svn>
DAV svn
SVNParentPath /my/laptop/backup/SVN
AuthType Basic
AuthName “Subversion repository”
AuthUserFile /etc/apache2/svn-auth-file
Require valid-user
</Location>


SVNParentPath was the magical incantation I needed. After that I was left only permissions to fix. That’s apparently where most people stumble. And its not my strong point. I can chmod 755 myscript.cgi like the rest of them, but dont ask me to explain what it (and all its possible variations) does exactly. I dug briefly into a nice tutorial on chmod, to grok the details once and for all, but found this walkthrough, and this one which instead supplied all the information I needed.


On OSX/Leopard I needed to use the www user, otherwise that was basically it.

1
sudo acpachectl restart
picks up the new apache config.
1
http://localhost/svn/my-repo
shows a directory listing of the repo, and:


svn co –username me http://localhost/svn/clients-repo \
/path/to/clients

…finally got me pay dirt - the full directory tree, with version history

A Parable

A man was asked to do some renovation on a house. He worked steadily at it for several weeks and finally called his client to come take a look around.

He said, “I was able to keep a lot of the original flooring. I got a good match for the wood and finish where I had to patch and extend the floor. I’m nearly done. I just need to pick up my offcuts and sweep up.”

“Oh good” said the client. “So I’ll arrange to start moving my family back in tomorrow. Sound OK?”

“Sure”.

The main picked up some of the debris, and noticed an ugly dark spot under a piece of paper. As he scraped at it, it revealed itself to be the end of a protruding steel rod. By scraping away around it, the man was able to get pliers on it and wiggle it. As he did, something clicked below the floor and now several of the boards creaked as he walked on them. Creaking was one of the things he’d been called in to fix, so he pried up those board to take a look. There he saw that the steel rod was actually a pin that had been rigged to hold together some structural beams. It had been driven down to sit flush with the floor, but was now rusted away and very fragile. As he stared in disbelief, the beams began to drift apart, the house sagged and collapsed in a pile of rubble.

Moral: A job is done or not done, never nearly done.

dijit.Declaration and its mixins

I love the dijit.Declaration widget introduced into the dojo toolkit around version 0.9+. It lets you declare a new widget class inline in your html - which can be very useful, especially when you want the widget templateString to be dynamic output from the server.

Just a little tip - I had been getting a

1
m._findMixin is not a function
error when instantiating widgets from my Declaration. If you’ve ever tried to step through widget instantiation you have an idea how sigh-worthy this particular error was. After a little debugging and poking through Declaration.js I noticed that the mixins property was typed as an array. When using dojo.declare directly, the parent class is the 2nd argument. And if you need mixins (like dijit._Templated) you make that 2nd argument an array and list them out in order as its content. So, it can be either a string or an array and dojo.declare will do the right thing. It turns out that with dijit.Declaration, the mixins property must be an array, even if you only have one value to put in there:

<div
dojoType="dijit.Declaration"
widgetClass="myns.widget.WidgetClassName"
mixins="[dijit._Widget]"
...
>...</div<

Which put me back in action, and I hope steers you around this particular hole in the road.

Regexp to match only html filenames and directory names

I’ve been working on a script to create filtered directory tree listings. It can be configured with both include conditions, and exclude conditions. If something passes the include filters, it then checks to see if its explicitly excluded. For example, I want to exclude cgi-bin, but include all other directories and files.

So its useful to have a good catch-all pattern for including only the good stuff. I needed only html files this time. So after some head scratching I came up with:

1
/(^.*\.htm(l?)$)|(^[^\.]+$)/

I dont like using .*, so to improve it maybe I could use a character range instead, or a negated range like [^.]+, but this works beautifully.

Simple Clocks with the Dojo Toolkit

Something I was playing with - this page shows a couple of javascript clock/countdown treatments. None are as whizzy as the dojox.gfx (vector graphics) clock you might have seen around, or your various dashboard widgets - but this is just dojo core + 6k (uncompressed) of code.