Blog Posts

Hello Berlin!

Well… that was a fun flight. We’ve missed the Bratwurst on Rails event that the Berlin Ruby folks were putting on, so it’s a simple matter of getting some sleep before heading over to the conference hotel at ungodly o’clock to register in time for the first of the Railsconf tutorials. If anyone knows of a good professional photolab in Berlin that can do black and white film dev + scan overnight, I’d be very interested to hear about it.

A tiny ruby niggle

You know what? I’m starting to miss compulsory semicolons as statement terminators in Ruby. “What?” I hear you say. “But not needing semicolons is one of Ruby’s cardinal virtues! Are you mad?” I don’t think so, but maybe you’ll disagree after I explain further. Here’s a piece of code that I might write if semicolons were the only way of terminating a statement: Category.should_receive(:find_by_permalink) .with(‘foo’) .and_return(mock_category); Or how about a complex find query def find_tags_for(tag_maker, order = ‘count’) klass = tag_maker.

Flash and Javascript, sitting in a tree...

We’re looking for somebody who can make Flash 8 and javascript play well together on IE 6/7, Firefox and Safari. If you fit the bill, please drop me a line at pdcawley@bofh.org.uk with a pointer or two to examples of your skills and you, me and my boss will have a nice little talk. We need a flash application which can be controlled via Javascript - we really don’t want to go sticking 10-15 tiny flash buttons on every page if we can help it, just so they can tell the main app (sitting in another window) that the user did something.

Typo stuff

If you’ve been running on the Typo edge recently, you’ll be all too painfully aware that there have been issues with the cache being flushed at the wrong times and not flushed at all at others. Which is not a happy state of affairs. However, I’ve recently got back to working on Typo and, after a few warmup refactorings and some missteps, I think caching is working properly now. There’s lots more work to do (there always is) but I reckon that you could do worse than bump your installation to r1513, which is what I’m running here.

Today's Noun Is: Notation

Remember back when I wrote about metaprogramming and programming being the same thing? Well, Libraries, Domain Specific Languages, Domain Agnostic Languages, Pidgins, YAML, .INI files and the like are all the same thing. They’re all notation. That’s the thing to remember. Good notation makes life easy. Bad (or inappropriate) notation makes it hard (or, in some cases, fun). There’s no point striving to write a pidgin or DSL if your problem can be solved easily enough with a well factored set of loosely coupled classes.

Today's noun is: Reification

Reification: The mental conversion of a person or abstract concept into a thing. Also, depersonalization, esp. such as Marx thought was due to capitalist industrialization in which the worker is considered as the quantifiable labour factor in production or as a commodity. - OED In the sense that the OED has it, I’m not what you could call a fan of reification. At work, we have a rule that anybody who starts talking about ‘resources’ when they mean ‘people’ gets a (verbal) slap.

Reading Beautiful Code

I’m reading ??Beautiful Code and it’s very good indeed. However, you have to feel sorry for Tim Bray - his chapter, “Finding Things” is excellent, as you’d expect. The only problem is, he’s following Jon Bentley, author of that perennial classic, Programming Pearls. It’s been a while since I (re)read anything by Bentley and I’d forgotten how good his prose was. Which isn’t to say that Tim Bray is a bad writer.

Five nouns for programmers

Reification Notation Reticence Lucidity Intent Learn ‘em. Live by them. What did I miss? Which ones don’t belong on the list. What am I talking about?

WTF?

A few days ago, Obie Fernandez: <typo:flickr img=“430323096” size=“small”/> commented on the advert found in the current Linux Journal which features a photograph of an attractive woman with the slogan “Don’t feel bad, Our servers won’t go down on you either.” Obie threw together a mock ad for a document management company which showed a bunch of latinos being harrassed by a US Customs and Immigration patrol with the slogan “Don’t worry.

A cunning (evil?) trick with Ruby

One of the handy tools that Ruby makes available to us Domain Specific Pidgin builders is instance_eval. With instance_eval you can take a block that was created in one context, with all its lovely closed over local variables, and evaluate it in the context of an instance of an arbitrary object. Which means that any references to instance variables and calls to methods are made as if your block were a 0 argument method of that class.

Domain Specific Pidgin

So, I’m busily writing an article about implementing an embedded little language in Ruby. It’s not something that’s going to need an entirely new parser, it borrows Ruby’s grammar/syntax but does some pretty language like things to the semantics and ends up feeling far more like at declarative language than the usual Ruby imperative OO style. Because I tend to chromatic’s view of many ruby programmers' ability to cry -“Wolf![]("- “DSL)”, I don’t want to claim that it’s a full blown Domain Specific Language, but it’s sufficiently language like that ‘API’ doesn’t seem to fit as a description either.

Monads

I’ve been following Adam Turoff’s excellent Haskell tutorial and he’s just reached the part where he explains Monads. To listen to a lot of people, Monads are the bit of Haskell that breaks their brains. As they’re usually described, Monads are the part of Haskell that allow you to write code that has side effects. You know, stuff like reading a file or generating a random number. What most of the tutorials I’ve read don’t do is explain why Monads let you use side effects.

Doing the fixture thing

Fixtures suck! Mocks rock! Don’t you dare let your tests touch the database! Well… yes… I suppose. Except, mocking can be a complete pain in the arse too (made slightly less of a pain in the arse if you use the null object options) - it’s awfully easy to end up with huge long setup methods that spend all their time faking out a mock object and about two lines testing what you need.

Deja vu all over again

Back when I was still programming Perl, one of the common mistakes that you’d see when people wrote lazily initialized object accessors was code like: sub get_content { my($self) = @_; $self->{content} ||= ‘default content’; } Code written like this would trundle along quite happily, until you had an attribute where, say, the empty string or 0 were legal values for the attribute. The problems were especially painful when the default value wasn’t something that perl treated as false.

Holiday Reading

Mmm… back from Scotland with a chunk of reading done: Harry Potter And The Deathly Hallows. Mmm… top notch stuff. Wraps up the series perfectly. The Book Thief. Wow! Seriously… wow. Whatever you do, don’t read the last chapter of this in public. I was a wreck. Beautiful. Sad. Really Sad. Life affirming stuff. Read it. The Complete Polysyllabic Spree. Nick Hornby writes exceedingly good litcrit/columns. Compilers: Principles, Techniques and Tools aka The Dragon Book.

Off on holiday

The bags are packed, there’s a pile of reading matter (mostly the classics, Turing’s papers, The Dragon Book…), the iPod is charged and we’re off to Scotland for a week with no connectivity. See you in a week. Don’t wreck the joint.

Theres Good Clever, and Bad Clever

Have you noticed the difference between Good Clever and Bad Clever? For instance, I recently spent a couple of hours working out to make a Genre model which acts_as_nested_list work in such a way that when ask one of the trunk genres for its tracks it finds all the tracks associated directly with the trunk or with any of the genre’s sub genres. It’s made doubly complicated by the fact that the genre is related to its tracks through a relationship model, and triply complicated that we’re going to want to be able to be able to search within the basic set of results (because, usually, we don’t want 300 tracks on a page…)

You never know when a coracle will come in handy

<typo:flickr img=“632526335” size=“small” /> A few years back, we got dad a place on a coracle building course as a birthday present. He had a great time and came back with a half finished coracle that he never quite got round to finishing. Until now, it seems. Despite what you might think, the photo above isn’t taken from inside my parents' boathouse, it’s taken from inside their garage. That’s not a river, that’s the road.

Cheat all you want, but don't get caught

As far as I can tell, one of the Smalltalk optimizers' mottoes is “Cheat all you want, but don’t get caught”. Well, this morning, I caught Squeak with its hand in the till. One way I attempt to bootstrap myself towards understanding of code is to try and make it better, if that makes sense. So, I’d run SLint over the OmniBrowser package and was trying to shorten a method. One thing that struck me as rather ugly was a piece of code that ran like this:

How I learned to stop worrying and love aggressive mockery

There’s something enormously liberating about writing an RSpec description that starts like: describe ArticlesController, “feeds:” do before do the_mock = mock('everything', :null_object = true) ActiveRecord::Base.stub!(:find).and_return(the_mock) end it “/articles.atom -> atom feed” do get :index, :format => ‘atom’ response.should render_template('_atom_feed') end … end The :null_object flag to rspec’s mock function is remarkably potent.The resulting mock will return itself from any method call that hasn’t got some other expectation set up.

Dogfood time again

So, I just pushed the first step of what I’m thinking of as the Great Typo Controller Reorganization to the typo repository and updated things here. It’s always scary when I do that - local testing’s all very well, but running on a live site is a different matter. I’ll be talking about the changes in a later post, there’s a couple of things in the recent change that I’m rather pleased with, as well as a Rails plugin that I hope will be widely useful, but which I need to document.

Deprecation! That's what you need!

So, I’m quietly beavering away at Typo with an eye to slimming down our somewhat monolithic ArticlesController class, tweaking our routing to use the new datestamped_resources plugin that I’ve developed to help dry up our routes, making a couple of new resourceful controllers for comments and trackbacks and generally tidying the place up. Hopefully Typo’s code is going to be much more habitable when I’m done. The problem is themes. Typo has an awful lot of ‘em.

The pleasures of baking

You know, I’m sure, how good fresh baked bread smells. But, good as that smell is, the real pleasure for me is the way it sounds. I’ve just pulled a loaf of sourdough bread out of the oven and it’s sat in front of me, scenting the air and rustling gently - it shrinks as it cools and that stresses the crust which occasionally gives up the battle with an audible crack.

The sky is not evil

Joss Whedon writes strong female characters, he’s the mind behind some of my favourite TV ever and he’s a wise man. Here he is reacting to seeing camera phone footage of the murder of Dua Khalil Aswad on CNN almost alongside the trailer for Captivity:

The trailer resembles nothing so much as the CNN story on Dua Khalil. Pretty much all you learn is that Elisha Cuthbert is beautiful, then kidnapped, inventively, repeatedly and horrifically tortured, and that the first thing she screams is “I’m sorry”.

“I’m sorry.”

What is wrong with women?

I mean wrong. Physically. Spiritually. Something unnatural, something destructive, something that needs to be corrected.

How did more than half the people in the world come out incorrectly? I have spent a good part of my life trying to do that math, and I’m no closer to a viable equation. And I have yet to find a culture that doesn’t buy into it. Women’s inferiority - in fact, their malevolence - is as ingrained in American popular culture as it is anywhere they’re sporting burkhas. I find it in movies, I hear it in the jokes of colleagues, I see it plastered on billboards, and not just the ones for horror movies. Women are weak. Women are manipulative. Women are somehow morally unfinished. (Objectification: another tangential rant avoided.) And the logical extension of this line of thinking is that women are, at the very least, expendable.

You should read the whole thing. Seriously.

Dress for success: wear a white penis

Metaprogramming == Programming

While I’m tilting a windmills, I should just like to tell all those people who bang on about ‘metaprogramming’. It’s all just programming. That is all.

Domain Agnostic Languages

Windmill tilting time again I’m afraid. Blame chromatic and David A. Black. What is it that characterizes domain specific languages? Before you trot out something like “Programs written in them read like domain experts talk”, take a look at some examples of code written in domain specific languages: /(?ms)"((?>[^\"]+)?(?>\.[^\"]))/ S3 R$* $: < $1 > R$+ < $* > < $2 > R< $* > $+ < $1 > R<> $@ < @ > R< $+ > $: $1 R@ $+ , $+ @ $1 : $2 R@ $+ : $+ $@ <@ $1> : $2 R$+ @ $+ $: $1 <@ $2> R$+ < $+ @ $+ > $1 $2 <@ $3> R$+ <@ $+ > $@ $1 <@ $2> >gi|2501594|sp|Q57997|Y577_METJA PROTEIN MJ0577 MSVMYKKILYPTDFSETAEIALKHVKAFKTLKAEEVILLHVIDEREIKKRDIFSLLLGVAGLNKSVEEFE NELKNKLTEEAKNKMENIKKELEDVGFKVKDIIVVGIPHEEIVKIAEDEGVDIIIMGSHGKTNLKEILLG SVTENVIKKSNKPVLVVKRKNS If you’re reading this on the front page, try and work out what the ones you recognise do before you dip below the fold.

Woohoo! Live comment previews are live.

Control.TextArea.ToolBar.Textile.js is currently rocking my world and, if you wish to comment on anything in this blog, will shortly be rocking yours I hope. I might need to fix up some of the feedback on commenting, but it’s nearly 1 in the morning and I’m going to bed.

Finally learning JavaScript

For years I’ve managed to dodge learning JavaScript. People have told me it’s a fine language with some dodge implementations. Friends have built an entire business model in the language, and I’ve continued to treat as if it were The Sound of Music (I’m 39 now and I have managed to completely avoid watching that film). Except, today I finally had a technical need that I couldn’t dodge by writing another .

What the?

Wow: $ rake spec … 156 examples, no failures $ ./script/spec spec … 156 examples, 2 failures $ rake [unit tests, all pass] [functional tests, all pass] [specs…] 156 examples, 2 failures For extra points, the 2 failures from running the plain rake are not the same as the failures from running ./script/spec spec. And if I run ./script/spec spec after a full rake run, I get a host of extra failures.

Things which are fun

It’s definitely fun to commit a major rework of something that’s been bugging you to SVN. It’s slightly less fun to check it out in your production server and have it fall over until you remember you to retweak the environment.rb file. Anyhow, we’re now running on Typo 4.1.1+r1438. Typo 4.1.1 got released last night and, pretty much as soon as it had cleared the gates I checked in a major rework of the Article and Feedback state mechanisms.

Other things which aren't fun

Last year, you would have been forgiven for thinking that Typo was pretty much dead in the water as an ongoing project. Typosphere was a placeholder, changes were few and far between, the app was a bloated monster. So, people switched, in droves, to Mephisto the new, (and excellent) kid on the block. Heck, even Tobi, the original author of Typo, has switched. Mephisto’s a great piece of software, and I’m as sure as I can be (without taking a closer look) that its underpinning code is cleaner than typo’s.

Things which aren't fun

Let’s say you’re running tests against your rails application and a test fails. “Hmm…” you think, “I wonder what could be causing that, let’s run that test file by itself.” The test passes. “Okay… I wonder if it’s the rake test loader, let’s run that test file using that.” The test passes “Right, it’s only the third test file on the list that’s failing, let’s try running just the first 3 test files.

Why don't more books work like this?

When you read Christopher Alexander’s ??A Pattern Language, the patterns within the language are interdependent and ordered from big patterns down to small ones. Each pattern has a number and wherever one pattern refers to another it’s referenced with both the pattern’s name and its number. Beck, Fowler and the Gang of Four (if memory serves) go one better, wherever they reference a pattern, they give the pattern’s page number (ah, the joys of computer typesetting).

Why I love Smalltalk

From Extreme UI Testing: Method wrappers. Easily possible in VW and Squeak since you can subclass CompiledMethod and much with the method dictionaries […] Niall uses a strategy pattern to automatically wrap threads that get forked off by looking up the stack to see if the code is under test (and if it is, make sure to install a wrapper) So what if the language doesn’t give me the callbacks I need, I’ll just rejig the system classes until it does.

Routing Speed

So, since I couldn’t sleep, I’ve been hacking on the routing drop in replacement. I’ve reached the point where things are mostly working and I can at least run the benchmark tests. On this machine, Rails recognizes routes at a rate of around 22K url/s. At the start of the night, with the recognizer rparsec, to do the recognition, my new routing system was running at around 5K url/s, which isn’t exactly great.

What happened to the routing rework?

Those of you who’ve been reading attentively will be aware that I’ve been working on a drop in replacemen for a chunk of Rails' routing subsystem. You will also be aware that things have gone a bit quiet on that front. I got a job. Which is lovely, and fabulous, and safeguards my mortgage payments and all that good stuff. But it has rather put dampeners on any non paying work.

That was fun

On Monday I was down in Brighton for a Brighton Coding Dojo where I had a crack at doing Kata four in Smalltalk. It took a while to find the balance, but once we got going I think it went well. We stuck in what seemed like the strangest places though. At one point, I had a method that did almost exactly what I wanted for a new method I was writing so I called up the method in the browser, changed the selector and the few bits that needed fixing up and accepted the changes.

Rails, CRUD, REST and the importance of adjectives

Consider a web request: GET /articles/2007/04/17/adjectives-rule;edit “What does it mean?" If we pass it through the prism of Rails routing, it breaks apart as follows: GET The :method, sometimes called the verb. /articles The :controller, the thing that’s going to handle this request /2007/04/17/adjectives-rule Parameters, passed to the controller method that handles this request ;edit The :action, some way of specifying what this request does It’s certainly one way of looking at it, but if you do I think you’re limiting your understanding of what it means to program in a RESTful fashion.

Soundbite

An argument for peace and love is always an argument for self-preservation. Go Giles Bowkett, you speak truth. You also speak it way better than I managed a couple of years ago.

Mmm... parsers

So, in my quest to get Rails routes to accept routes like: articles/:comment[article]/comments/:comment[id] I’ve been playing with parsers for the first time in my programming career. Quite how I’ve managed to get this far without them I leave as an exercise for the interested reader. At the moment I have a parser that will parse articles/2007/05/12/slug and give back an ActionSelector that yamlizes as — !ruby/object:ActionSelector controller: articles action: show params: :article: :year: 2007 :month: 05 :mday: 12 :slug: slug Which can be easily turned into the kind of params hash that rails wants from its routing system in order to dispatch the request to the right place.