Episode 63: Model Name in URL

Posted about 7 years back at Railscasts

By default, Rails uses the model's id in the URL. What if you want to use the name of the model instead? You can change this behavior by overriding the to_param method in the model. Watch this episode for details.

Refactoring by Martin Fowler - Developer must have

Posted about 7 years back at work.rowanhick.com

Late last year I was spending a lot of time on trains between T.O and Montreal, on one trip I picked up this book and was thoroughly engrossed - Refactoring - Martin Fowler is one of those simply must-have books on any developers bookshelf. Of all technical books I've found it to be the one that actually compels you to be a better programmer. The first chunk of the book is dedicated to whats, whys, testing etc of how you should turn your mish-mash of spaghetti code into beautiful elegant world class code, the rest of the book is dedicated to a catalog of various examples of refactorings. Each refactoring is structured with a small class diagram, theory about why you want to do it, then a detailed walk through of the steps written to get there. Well written, most of them are a doddle to understand. Even though the book uses examples in Java, they equally can apply for your Ruby, PHP, Actionscript code or whatever else tickles your fancy. If you want to change from a programmer to a code artisan, this is the book for you. If not we'll leave you alone with your unmaintainable spaghetti code. Some of the refactorings are obvious, and some the light switches on and you go 'a-ha'. Certainly if I'd have had this book from day 1 many moons ago I would've been a much happier chappy. I know using principles in the book I came away refactoring a working but messy piece of code days after reading it - the principles learned in the book made it a lot easier and quicker to do. One big personal improvement I made was towards not being afraid of breaking up functions for readability e.g. like so: class MyClass def able_to_checkout if ( ugly_condition_1 == a && ugly_condition_2 == c && you_get_the_picture ) self.set_book_to_checked_out end end (guilty as charged) to the following: class MyClass def able_to_checkout if ( no_books_checked_out? ) self.set_book_to_checked_out end end def no_books_checked_out? ugly_condition_1 == a && ugly_condition_2 == c && you_get_the_picture end end To round off the book, it's a hard cover with a little red cloth tape bookmarker. What other technical book have you seen with that in recent history ? It's been designed to stay on your shelf for a very long time - unlike some faded examples gathering cobwebs on mine. A rare timeless classic ? Quite possibly. Go out and buy it today if you haven't already. Another 10 | 10

How do you process literature?

Posted about 7 years back at Saaien Tist

A quick glance at the side of my desk reveals two stacks of manuscripts to read; each stack about 20cm high. Sounds familiar? There seems to be a major task in front of me to process all that.
First thing to do is to identify what caused those piles in the first place. The answer: no system that I'm satisfied with for reference management. Of course, there is software like Reference Manager and EndNote as well as websites like Connotea and CiteULike. But they all have one major flaw: they are not suited to store the knowledge gained from those papers. Entering a reference to those papers in the software is not the same as going through them and extracting useful information. Sure, they do have a notes field where you can jot down some short remarks, but often knowledge is much easier recorded and remembered in little graphs and pictures than in words. There's reference management, and there's knowledge management.

What do I want my system to look like? First of all, it should be searchable. The tagging system provided by CiteULike/Connotea seems good for that. Also (and this might seem illogical for a bioinformatician), the system should not be fully automatic or even electronic, but analog. Why? Just pressing a button to for example add the abstract from a paper to the system gives a sense of... what's the word in English: volatility? For some things you should use the help of a computer, and for some you shouldn't. There's a difference between using Excel to repeat the same calculation 50 times, and trying to use a pc for storing knowledge. It's me who needs to store that knowledge, not the computer. If that was the case, I could always go back to Google instead of making the effort of using a reference manager in the first place. I've played around with zotero and personal wikis in the past, and they just didn't do the trick: I still ended up just copy-pasting the information instead of absorbing it.

Another advantage of using an analog system, is that when you feel your productivity behind your computer is suboptimal, you can always take your cards, find yourself a quiet place, put your feet on a desk, and flick through the things you wrote down. Slippers and pipe are optional.

During my PhD a few years ago, I used a system that was exclusively based on index cards. The inspiration came from Umberto Eco's book "Come si fa una tesi di laurea" (Or "How to make a doctoral thesis") (1977) in which he explains how he handles the knowledge for his book research. For each manuscript, I'd make a new card. The front contained an identifier, the paper title, full reference and keywords. On the back I'd write down what I had to remember from that paper, including little graphs, schemas and stuff. I've got to admit that a drawback of using these cards was that they were not easily searchable, but linking them worked quite well with a bit of discipline.
During those years, I used the index card system both as reference manager and as knowledgebase. Although it did work to satisfaction, the role of reference manager should be fulfilled by a better tool.

Now how could I implement something like that into a workflow? Basically, any new paper to be read should be entered in CiteULike and tagged as 'to_read'. When I've got time to read it: see if it's necessary to print out, or preferably read from the screen (we want to be nice to the trees, don't we?). When I've read the manuscript and there is interesting information to remember, only then create an index card. In case it's a landmark paper and/or I've been adding a lot of comments and markings in the text: keep the printout as well, and mark the index card that I've got that printout as well.
Let's try this out for a few weeks and see where it goes...

BTW: for a knowledgebase system based on index cards taken to the extreme, see PoIC (Pile of Index Cards).

Episode 62: Hacking ActiveRecord

Posted about 7 years back at Railscasts

Have you ever wanted to temporarily disable all validations? Well, ActiveRecord doesn't support this, but that doesn't mean we can't add it. This episode will show you how to open up an existing class and change its behavior.

Impressed With Comatose CMS

Posted about 7 years back at zerosum dirt(nap) - Home

Often after I’m finished building the bulk of a web app, I find there are some secondary pages that need to be built. These pages are largely informational, such as an about page, a contact page, an FAQ, etc. They’re relatively static in terms of the content, but it’s always nice if we can supply our client (or ourselves) with a nice CMS-style interface to make updating them easy, and within the context of our existing application layouts. Keep it simple, keep it DRY.

The obvious thing is to cook up some sort of PagesController from scratch. This is nice because it’ll make use of your existing facilities, your authentication/authorization system, layouts, etc. It is custom, after all, and a custom fit is almost always the best fit. But it’s a fair bit of work for something that’s probably not ‘core’ to the application, and takes cycles away from other places they could be better spent.

On the other hand, you can integrate with a 3rd-party CMS or blogging package like Typo, Radiant CMS, or Mephisto. They’re all great packages and do what they do really well. The downside is you’ve got to write a fair amount of glue to hook everything together and make it look (and feel) uniform.

Another option is to use Matt McCray’s Comatose plugin, a micro CMS. It’s got all the basic functionality you want for this sort of stuff out of the box and it couldn’t be much easier to use. The real bonus is integration is almost completely seemless, which makes it (imho) the best of both worlds for this sort of project.

Installing the plugin gets you a ComatoseController and a ComatoseAdminController. You add an entry (or multiple entries, if you like) in your routes file to tell your application when to invoke the ComatoseController. You might prefer a scheme where all URLs starting with /pages are passed to Comatose, for example. Then you log into the admin controller (which also needs an entry in routes) to create the pages. All the basic management tools we need are here; pages are organized hierarchically and can be edited with great ease, using a variety of markup filters. Each page gets a number of attributes, including a title, keywords, author, etc.

Basically it’s everything we need for the bare-minimum no-frills CMS experience and nothing we don’t. Which is just the way I like it. Check it out for your next project.

UPDATE

Anyone having issues with Comatose and authentication should check out this bug report. If you’re specifying an alternate session key, you should put it in environment.rb instead of ApplicationController.

ActionController::Base.session_options[:session_key] = "_your_custom_session_id"

Comatose controllers inherit directly from ActionController::Base instead of from your application controller. So if you specify the session key in application.rb, the Comatose-driven sections of your app will be blissfully unaware of it. This means a method like logged_in? (which checks the session for your login status) will always report back as false.

Episode 61: Sending Email

Posted about 7 years back at Railscasts

This is a brief guide to sending email in Rails. See how to configure the environment, generate a mailer, create a template, and deliver the mail.

XChain - it has a name, license, and home.

Posted about 7 years back at work.rowanhick.com

The open source Rails/Flex eCommerce application now has a name - XChain - pronounced cross-chain. I had some air travel time over the weekend and put it to good use coming up with a name, the basic premise being that the app should really be classified as a Supply Chain Management system as it deals with a lot more than simply taking peoples money for a product. (Order fulfillment, shipment tracking, eventually CRM and inventory management), and being a cross of two major technologies it seems to fit. Catchy enough and has meaning. Well I think so anyway, others might disagree - (that's what the comments form at the bottom is for...), only downer is XChain.com is taken by some spammer, but I've snapped up .ca and other appropriate domains. To this end, I've also created a home for it here http://code.google.com/p/xchain/ which seems to be a good location for now, satisfies the free and accessible by SVN requirements. Alas no RSS feed, so stick to here for the updates. I'm not a lawyer by any stretch, and have to a little more digging, but have basically decided on a license for it. The Mozilla Public License. My wish is that anyone will be able to use it for either non-commercial and commercial applications free of charge. The only restriction is if you extend it, you have to provide source code back to the community. I believe this is fair enough as you will be getting a tonne of usable code out of the box to start with. I just need to check that we can provide mechanisms for companies sensitive proprietary processes - to make sure these can be wrapped up in a separate lib, or DSL stored in the db, to make sure that doesn't need to be opened up to the outside world. Final decision of the day is to go with Cairngorm - this has more exposure so will hopefully appeal to a wider base of developers, and seems more suited to the scale of this application. I also found a Cairngorm Rails code generator via onrails.org which looks like it will do the business saving time generating code. Right, time to get some code into that repository.... in the meantime feel free to let me know your thoughts on the name and license choice.

New DRYML - Part 1

Posted about 7 years back at The Hobo Blog

As I’ve mentioned a few times, there’s lot of breaking changes in the “new DRYML”. In some ways there’s not a huge amount of new functionality, but we really feel it’s much cleaner and more elegant now. I’ll go over the new features in this and probably one or two further posts.

If you want to try any of this out, Hobo 0.6-pre1 has been tagged in the repository:

  • svn://hobocentral.net/hobo/tags/rel_0.6-pre1

It’s just a preview though and you’ll likely encounter bugs. We won’t we updating the website or releasing a gem.

Changes to current features

Let’s start by working through some features from the perspective of changing an app to work with the new DRYML.

A bunch of names changes

The hobolib directory (app/views/hobolib) is now taglibs. We wanted to make Hobo feel less like an add-on and more integrated.

<taglib> is now <include>

The part_id attribute for creating ajax parts is now simply part. Hopefully this will help avoid some confusion about the different roles in the ajax mechanism of part names and DOM IDs.

The xattrs attribute for adding a hash-full of attributes to a tag in one go is now merge_attrs.

Code attributes

Code attributes are now signified with & instead of a #, so for example:

<if q="&logged_in">

Instead of

<if q="#logged_in">

The reason for the change is that you can now use #{...} at the start of an attribute, e.g.:

<button label="#{name} is my name" />

field and with instead of attr and obj

To set the context to some field of the current context you now say field="..." instead of attr="...". You can also use a new shorthand:

<repeat:comments> ... </repeat>

Notice the :comments part is missing from the close tag (that’s optional).

To set the context to any value, use with="&..." instead of obj="#..."

Bye bye parameter tags, hello templates

Parameter tags used to offer an alternate syntax to attributes for passing parameters to tags, so

<page title="My Page"/>

Was the same as

<page><:title>My Page</:title></page>

It looks great in a simple example like that, but in practice this feature was getting messy. Looking at some DRYML code, it was far from obvious why you’d be using a <:parameter_tag> in one place and a <normal_tag> in another. And what happened when you had a tag-body and parameter tags? That was even messier. And what about inner tags? Are they another name for parameter tags or something different? And then there was the mysterious content_option and replace_option. Which one should I use? Why?

So now there are no parameter tags, and instead there are template tags. Templates are a new kind of tag you can define:

  • They are distinguished form normal tags because the name is in <CamelCase>
  • They don’t have a tag-body. You never user <tagbody> in a template definition
  • Templates have attributes like regular defined tags. They also have parameters
  • A parameter is a section of content that the caller of the template can augment or replace
  • You create a parameter by adding the param attribute to any tag inside the template

Here’s an example:

<def tag="Page">
  <html>
    <head param="head">
      <title param="title" />
    </head>
    <body param="body">
      <div class="header" param="header" />
      <div class="main" param="main" />
      <div class="footer" param="footer" />
    </body>
  </html>
</def>

(note: it’s quite common that the parameter name is the same as the tag name, as in <head param="head">, in this case you can omit the parameter name, e.g. <head param>)

When calling this template, you can provide content and attributes for any of thed parameters. You can also append and prepend to parameters, or even replace parameters entirely:

<Page>
  <title>My Page</title>
  <head.append>
    <script src="..."/>
  </head.append>
  <body onclick="runMyScript()"/>
  <header>
    ...my header...
  </header>
  <main>
    ...my content...
  </main>
  <footer.replace/>
</Page>

To explain what’s going on in terms of “old DRYML”, it’s as if every child of <page> is a parameter tag. <title>, <head>, <body> etc. are neither defined tags or plain HTML tags. They are template parameters. The attributes and content of these tags are passed to the template and appear in the appropriate places.

Parameters can be called with various modifiers. In the above example we see <head.append>, which adds a script tag to the head section, and <footer> which replaces the footer entirely – in this case with nothing at all, so the footer is simply removed. The full set of these modifiers is:

  • append: append content to the body of the parameter
  • prepend: prepend content to the body of the parameter
  • before: insert content just before the parameter
  • after: insert content just after the parameter
  • replace: replace the parameter entirely

The power really kicks in with the fact that you can nest parameters, but I think that will have to go in part 2, along with local tags, control attributes and a few other bits and bobs…

New DRYML - Part 1

Posted about 7 years back at The Hobo Blog

As I’ve mentioned a few times, there’s lot of breaking changes in the “new DRYML”. In some ways there’s not a huge amount of new functionality, but we really feel it’s much cleaner and more elegant now. I’ll go over the new features in this and probably one or two further posts.

If you want to try any of this out, Hobo 0.6-pre1 has been tagged in the repository:

  • svn://hobocentral.net/hobo/tags/rel_0.6-pre1

It’s just a preview though and you’ll likely encounter bugs. We won’t we updating the website or releasing a gem.

Changes to current features

Let’s start by working through some features from the perspective of changing an app to work with the new DRYML.

A bunch of names changes

The hobolib directory (app/views/hobolib) is now taglibs. We wanted to make Hobo feel less like an add-on and more integrated.

<taglib> is now <include>

The part_id attribute for creating ajax parts is now simply part. Hopefully this will help avoid some confusion about the different roles in the ajax mechanism of part names and DOM IDs.

The xattrs attribute for adding a hash-full of attributes to a tag in one go is now merge_attrs.

Code attributes

Code attributes are now signified with & instead of a #, so for example:

<if q="&logged_in">

Instead of

<if q="#logged_in">

The reason for the change is that you can now use #{...} at the start of an attribute, e.g.:

<button label="#{name} is my name" />

field and with instead of attr and obj

To set the context to some field of the current context you now say field="..." instead of attr="...". You can also use a new shorthand:

<repeat:comments> ... </repeat>

Notice the :comments part is missing from the close tag (that’s optional).

To set the context to any value, use with="&..." instead of obj="#..."

Bye bye parameter tags, hello templates

Parameter tags used to offer an alternate syntax to attributes for passing parameters to tags, so

<page title="My Page"/>

Was the same as

<page><:title>My Page</:title></page>

It looks great in a simple example like that, but in practice this feature was getting messy. Looking at some DRYML code, it was far from obvious why you’d be using a <:parameter_tag> in one place and a <normal_tag> in another. And what happened when you had a tag-body and parameter tags? That was even messier. And what about inner tags? Are they another name for parameter tags or something different? And then there was the mysterious content_option and replace_option. Which one should I use? Why?

So now there are no parameter tags, and instead there are template tags. Templates are a new kind of tag you can define:

  • They are distinguished form normal tags because the name is in <CamelCase>
  • They don’t have a tag-body. You never user <tagbody> in a template definition
  • Templates have attributes like regular defined tags. They also have parameters
  • A parameter is a section of content that the caller of the template can augment or replace
  • You create a parameter by adding the param attribute to any tag inside the template

Here’s an example:

<def tag="Page">
  <html>
    <head param="head">
      <title param="title" />
    </head>
    <body param="body">
      <div class="header" param="header" />
      <div class="main" param="main" />
      <div class="footer" param="footer" />
    </body>
  </html>
</def>

(note: it’s quite common that the parameter name is the same as the tag name, as in <head param="head">, in this case you can omit the parameter name, e.g. <head param>)

When calling this template, you can provide content and attributes for any of thed parameters. You can also append and prepend to parameters, or even replace parameters entirely:

<Page>
  <title>My Page</title>
  <head.append>
    <script src="..."/>
  </head.append>
  <body onclick="runMyScript()"/>
  <header>
    ...my header...
  </header>
  <main>
    ...my content...
  </main>
  <footer.replace/>
</Page>

To explain what’s going on in terms of “old DRYML”, it’s as if every child of <page> is a parameter tag. <title>, <head>, <body> etc. are neither defined tags or plain HTML tags. They are template parameters. The attributes and content of these tags are passed to the template and appear in the appropriate places.

Parameters can be called with various modifiers. In the above example we see <head.append>, which adds a script tag to the head section, and <footer> which replaces the footer entirely – in this case with nothing at all, so the footer is simply removed. The full set of these modifiers is:

  • append: append content to the body of the parameter
  • prepend: prepend content to the body of the parameter
  • before: insert content just before the parameter
  • after: insert content just after the parameter
  • replace: replace the parameter entirely

The power really kicks in with the fact that you can nest parameters, but I think that will have to go in part 2, along with local tags, control attributes and a few other bits and bobs…

Episode 60: Testing without Fixtures

Posted about 7 years back at Railscasts

Tests which rely heavily on fixtures are brittle and can be difficult to maintain. This episode will show a couple techniques for creating tests which don't use fixtures.

Essential Actionscript 3 - Essential !

Posted about 7 years back at work.rowanhick.com

The great chapters.ca boat sailed into port - last week Essential Actionscript 3.0 by Colin Moock arrived on my doorstop. First impressions this is by far the biggest tech book to grace my shelves. 900+ pages worth, it dwarfs O'Reillys recently released Programming Flex 2 book. This book really does cover everything from general programming skills to the nitty gritty of E4X useage. The work that has gone into this book by Mr Moock shows. Approximately the first ~350 pages of the book is devoted to Core Actionscript & OOP principles in general, the second half Flash/Flex features such as XML, Drawing API, Security etc. Coupled with the Programming Flex 2 book I really think that's all you need for your bookshelf. My learning style is to learn by example (I skim read text - but thoroughly read code to understand) which is covered off really well, the vast majority of pages have a short code fragment or diagram to complement the text along with longer full code examples where applicable. Essential AS3 has depth to each and every topic, the ones I've read thus far anyway, going through example after example illustrating different facets of the topic - the XML chapter was particularly impressive. Too often you read a book and feel like you have to go back to the great Google Gods to discover more, whereas with this book I feel like that's all I need right there. All in all, the best tech book I've purchased (even over the famous Agile Web Development with Rails book). Value for money can't be beat, cost me about $55CAD to my doorstep - and illustrates how thankful I am living in Canada now, after being used to New Zealand book prices! It's already taken pride of place by the keyboard as I'm working on our new widget seller solution. 10|10

Low Pro Behaviours 101: Part 2

Posted about 7 years back at danwebb.net - Home

In the first post I briefly explained how to use pre-made Low Pro behaviours but, although I’m in the process of writing a few myself, Low Pro is not going to be a widget library – what it is is a great framework to write your own components with. So, in this post, I’m going to go into a little detail about how to write your own behaviours. If the idea of that doesn’t bore your rigid then read on…

Creating a behaviour

As discussed in the last post behaviours are actually just specialised constructor functions. So, to create our behaviour we use Behavior.create in a very similar way to Class.create:

var Hover = Behavior.create();

Adding methods and properties

This creates an empty behaviour much the same as Class.create gives us an empty class. Now we add our methods on to the prototype of the constructor that we’ve created. This example is a super simple behaviour, Hover, that will add/remove a class name (which you can specify) on mouse over/out:

Object.extend(Hover.prototype, {
  initialize: function(className) {
    this.className = className || 'over';
  },
  onmouseover: function() {
    this.element.addClassName(this.className);
  },
  onmouseout: function() {
    this.element.removeClassName(this.className);
  }
});

Any on* methods are bound as event handlers to the element when the behavior is attached to the element. The scope of these methods is ‘corrected’ automatically so that this will always refer to the behaviour instance. The behaviour instance also has a magic property, this.element, which points to the element it is attached to. The final thing you need to know is that the initialize method is called as soon as the DOM is ready (as soon as the element is available). We can now use this behaviour in the manner discussed in the last post:

Event.addBehavior({
  '.dongle': Hover('hover')
});

Aside from these special cases behaviour constructors are identical to any regular JavaScript ‘class’. You can add methods and properties as you see fit. Note that each element that has the behaviour attached to it gets its own instance of the behaviour so you can maintain the state of each behaviour independently without having to resort to setting expandos on the element, using closures or any other method which is messy and prone to causing those nasty circular references that cause memory leaks. As an alternative you can just pass your methods straight into the Behavior.create call so the following is equivilent to the above code:

var Hover = Behavior.create({
  initialize: function(className) {
    this.className = className || 'over';
  },
  onmouseover: function() {
    this.element.addClassName(this.className);
  },
  onmouseout: function() {
    this.element.removeClassName(this.className);
  }
});

Working with multiple elements

Now this is all good for dealing with behaviours that work on a single element but in many cases we want a behaviour to operate on a number of elements. For example, you would want to be able to attach a Sortable behaviour to a list element but the behaviour itself would also need to deal with all the list element inside it. There are a number of ways to approach writing these kind of behaviours, all of which are demonstrated in the various test behaviours I’ve written.

Event delegation with behaviours

The first technique, and normally the best is using event delegation to capture all the events on elements inside the attached element with your behaviour and process them. The process is pretty simple…here’s part of the Calendar behaviour:

var Calendar = Behavior.create({
  // other methods hidden for clarity
  onclick : function(e) {
    var source = Event.element(e);
    Event.stop(e);

    if ($(source.parentNode).hasClassName('day')) return this._setDate(source);
    if ($(source.parentNode).hasClassName('back')) return this._backMonth();
    if ($(source.parentNode).hasClassName('forward')) return this._forwardMonth();
  }
});

Here, we define a single onclick method which will capture clicks on all the elements inside the calendar – Forward and back arrows, and the dates themselves. Firstly, we use Event.element to grab the source element, the element that was actually clicked, then we can just examine this element to work out what needs to happen to the calendar and call the relevent method. In this case, and in most cases, the most convenient way is to look at what class names the element has. In the calendar, each day has the class ‘day’ and the forward/back arrows have the classes ‘forward’ and ‘back’. This method is really nice for a number of reasons, firstly, we avoid attaching lots of event handlers for each sub element and secondly we have this central point where we can handle and dispatch events – a really pleasant way to work with complex interactions. Of course, event delegation isn’t always a good fit so…

Linking behaviours

In more complex cases when the sub elements of your behaviour need to maintain their own state or handle events in a more complex way you can have your main behaviour attach sub-behaviours to inner elements during initialisation and maintain a link between the two. An example of this can be seen in the Draggable behaviour:

Draggable = Behavior.create({
  initialize : function(options) {
    // code hidden for clarity
    this.handle = this.options.handle || this.element;
    new Draggable.Handle(this.handle, this);
  }
  // code hidden for clarity
});

Draggable.Handle = Behavior.create({
  initialize : function(draggable) {
    this.draggable = draggable;
  },
  onmousedown : function(e) {
        // code hidden for clarity
  }
});

Here, the initialize method of Draggable finds the element that it wants to be the ‘drag handle’ and attaches another behaviour, Draggable.Handle, to it. At this point we pass a reference to the Draggable instance to the Draggable.Handle instance so the drag handle can refer back to and control the main draggable behaviour. You can of course, if necessary, build up a complex component by building a number of linked behaviours that all comunicate back to the main behaviour.

Get it? Got it? Good

So that’s all for now. Any questions just drop me a comment and I’ll get back to you ASAP. At this point, if you are interested in writing your own behaviours then it would be worth referring to the behaviours in SVN. However, I’m just feeling this out for myself and I’m sure I’ve not explored any near all of the possibilities of working with behaviours so if you have any brain waves be sure to post a comment also. If there’s enough interest I might include a behaviours repository on the upcoming Low Pro site.

Documenting one-off parsers

Posted about 7 years back at Saaien Tist

A lot of day-to-day work consists of parsing data files to transform the contents from one format into another or to create statistics. However, when you have to get back to those scripts at a later stage - you need something similar in another project or you notice that something along the way must have gone horribly wrong - it can often be quite hard to figure out what the script actually did. Having meaningless script filenames like ParseBlast.rb doesn't help either. (Parse BLAST into what?)

I must say that things improved a lot when I switched from perl to ruby. Trying to understand a perl script that I wrote a couple of weeks earlier was a real pain, while I normally have no problems understanding ruby code that I wrote months ago... Has a lot to do with the simple syntax and expressiveness (is that a word?) of that language.

But just understanding the code is not enough. To be able to assess if you could use a script from an earlier project in a new one, you often also have to get hold of information in that script that is not inherently encoded in its code: what was the project? What did the input look like? What did the output have to look like? That's where the script documentation comes in, because having that information easily available greatly reduces the time you need to assess if you should copy-paste-adapt the script, or just start from scratch.

What I try to do, is always use the same template when starting a new parsing script. Even when the parsing itself would only take 5 lines, I try to use this whole template. A quick walk-through:

Lines 2-32: The documentation, consisting of:

  • script name
  • short usage message
  • a description of what the script does
  • list of arguments that can be used
  • input format
  • output format
  • contact information
Lines 38-40: Definitions of classes that are used later on in the script itself
Lines 42-51: Parsing the arguments to the script. If the user (i.e. me when I run it) uses --help or an argument that does not exist, he automatically gets the documentation of the script. If I would use the -a tag here, the output to the screen would be

USAGE
-----
./this_script.rb [ -h | --help ]
[ -i | --infile | < ] your_input.txt [ -o | --outfile | > your_output.txt ]


Lines 53-58: Logging of the options that were used in running the script.
Lines 60-70: Create the input and output streams.
Lines 72-75: The actual parsing code. This is the bit that does the work (using the classes described in lines 38-40).
Lines 77-79: Clean up.

Here's the complete template.

#!/usr/bin/ruby
# == NAME
# this_script.rb
#
# == USAGE
# ./this_script.rb [ -h | --help ]
# [ -i | --infile | < ] your_input.txt # [ -o | --outfile | > your_output.txt ]
#
# == DESCRIPTION
# Description of what this script does...
#
# == OPTIONS
# -h,--help:: Show help
# -i,--infile=INFILE:: Name of input file. STDIN if not defined.
# -o,--outfile=OUTFILE:: Name of output file. STDOUT if not defined.
#
# == FORMAT INPUT
# >gi|4531835|bla
# ACTTACCGACCGACTGACTACTTATGCCA
# >gi|4861534|blabla
# CTACCCCATCTACCGGGGCTCGACT
# ...
#
# == FORMAT OUTPUT
# 4531835 29
# 4861534 25
# ...
#
# == AUTHOR
# my full contact information

require 'rdoc/usage'
require 'optparse'
require 'ostruct'
require 'logger'

### Define classes here
class MyClass
end

### Get the script arguments and open relevant files
options = OpenStruct.new()
opts = OptionParser.new()
opts.on("-h","--help",
"Display the usage information") {RDoc::usage}
opts.on("-i","--infile", "=INFILE",
"Input file name") {|argument| options.infile = argument}
opts.on("-o","--outfile", "=OUTFILE",
"Output file name") {|argument| options.outfile = argument}
opts.parse! rescue RDoc::usage('usage')

log = Logger.new(File.new('this_script.log', File::WRONLY | File::TRUNC | File::CREAT))
log_level = Logger::INFO # or: DEBUG, WARN, FATAL, UNKNOWN

log.info('Script this_script.rb started')
log.info('Options:')
log.info(options.to_yaml)

if options.infile
input_stream = File.open(options.infile)
else
input_stream = $stdin
end

if options.outfile
output_stream = File.new(options.outfile,'w')
else
output_stream = $stdout
end

### Actually do some stuff
input_stream.each_line do |line|
output_stream.puts line
end

### Wrap everything up
output_stream.close
input_stream.close

(If I wanted this a bit DRYer, I'd have a constant with the script name at the top so I wouldn't have to repeat that filename over and over. To be done...)

If I wanted to over-organize, I'd create a little database with the descriptions of those scripts so I can search through them. Even though that would have it's use from time to time, that would be taking it too far. Having that documentation and a standard way of providing the command line arguments is enough for me for now.

I must admit I let this slip in the last couple of months, which doesn't mean it didn't work the months before that. That's just what happens when you go on holiday and completely forgot the habit of doing this afterwards.

UPDATE: InfiniteRed blogged about a similar approach later.

Episode 59: Optimistic Locking

Posted about 7 years back at Railscasts

When two people attempt to update the same record near the same time, one of the updates will likely be overwritten. You can solve this problem with optimistic locking.

Low Pro Behaviours 101

Posted about 7 years back at danwebb.net - Home

Okay, I’ve gone on about this for long enough and made lots of promises. So now’s time to make a start on explaining all this business with Low Pro and ‘behaviours’.

Behaviours are part of Low Pro and are object orientated mechanism by which you can handle events and maintain the state of an element (or indeed a set of elements) and as I’ve found out recently are an incredibly nice way of writing and deploying UI widgets. Before I dive in to how to write your own behaviours, let’s get a flavour for how to use them. If you want to play along you’ll need the latest versions of Prototype and Low Pro as well as the remote behaviours which you can grab from my SVN.

The first thing to note about a behaviour is that they are simply specialised constructor functions so you can use them with the new keyword to create an instance:

var aLink = $('edit_5');
var ajaxLink = new Remote.Link(aLink, { method: 'post' });

Behaviours, when used with the new keyword, always take an element reference as the first argument. Any subsequent arguments are passed to the behaviours constructor. In the case above, Remote.Link is a behavior which when attached to a link will make the link trigger an Ajax request rather than a tradtional page refresh. With this behaviour the second argument is an options hash that is passed through to the Ajax request. Now we’ve created an instance of the behaviour that instance of the behaviour is bound to that element for it’s life time on the page handling click events on the link and sending Ajax requests.

If you need to attach a behaviour to multiple elements on then using new could get a little tedious. To this end behaviours work very nicely with Event.addBehavior:

Event.addBehavior({
  'a.edit': Remote.Link
});

Using a behaviour with Event.addBehavior in this way will attach a seperate instance of the behavior to every element that matches the CSS selector. Notice we don’t pass in an event in the selector as you might be used to. The behaviour knows what events it wants to listen for. Now all the links in the page with the class name ‘edit’ will invoke Ajax request. You may need to pass in extra information to the behaviour as we did above with the options hash. Thanks to a bit of metaprogramming hackery we can do this too:

Event.addBehavior({
  'a.edit': Remote.Link({ onComplete: triggerEdit })
});

As you can see, it’s almost like CSS for interactivity where you’re defining how elements behave in an declaritive, almost code-less fashion. In my own projects I’ve gained massive advances in maintainability by separating everything out into behaviours then using Event.addBehavior as the glue to my HTML. You don’t need to use custom HTML attributes or weird classnames – you just bind behaviours to elements as you would style rules in CSS.

Of course, using this method you don’t get references to the behaviour instances you’ve created. In fact, you’ll hardly ever need to get references to these behaviour instances as most behaviors don’t need public methods at all but in case you need to get at them there’s a property of each behavior that contains an array of all its instances on the page:

Remote.Link.instances //=> an array of all the instances of Remote.Link

So that’s basically how to use behaviours. In a day or two I’ll post part two of Behaviours 101 which will show you how to make your own but in the meantime try out some of the behaviours I’ve already created. So far there’s a Draggable, Droppable, A date picker, Remote link and Remote form. Check out the demo page.