At work, we’re looking at adding the Atom Publishing Protocol in a few places where it makes sense. APP’s got a lot going for it - the spec is a great example of how to design a Resourceful API and is worth reading even if it’s not an immediately good fit for your application.
But…
#
It’s one of the givens of good application security that you don’t store passwords in clear text and you do your level best not to send them over the wire in cleartext. That way, if someone pinches your user database, they should have their work cut out for them if they want to find out what your password is (because, unless you’re very good or are using something like 1password, you probably use the same password for lots of different websites).
Martin Fowler is writing a book about Domain Specific Languages and, because you could never accuse Martin of a lack of ambition, he’s trying to write it in a reasonably (implementation) language agnostic fashion.
It’s fairly easy to write an implementation language agnostic book about old school DSLs, what used to be called little languages - there’s a fairly well established literature and theory to do with lexing, parsing and interpreting. These are all about algorithms, and algorithms are implementation language neutral by their very nature.
I’ve been busily adding AJAX features to the work website, and I got bored of writing Form handlers. I got especially bored of attaching similar form handlers to lots of different forms on a page, so I came up with something I could attach to document.body
and then plug in handlers for different form types as I wrote them.
So, I wrote FormSender
and set up my event handler like so:
… timing. You either have it or you don’t.
Does this count as good timing?
- Finish up some improvements to the way Typo sweeps cached pages
- Announce Typo 5.0
- Go down with a horrible cough and cold that leaves you exhausted and incapable of hacking
- Discover that the ‘improvements’ in Typo’s cache sweeping can, occasionally, cause it to wipe the entire Typo installation directory
- Stagger out of bed. Attempt to fix problem
- Release Typo 5.0.1
- Discover that the fix doesn’t work
- Bleargh!
- Let your co-maintainer deal with the fall out before releasing Typo 5.0.2 which does fix the cache sweeper
- We hope
- Recover enough to write a blog entry
Okay folks, Typo 5.0.2 is out and it appears to be working. I’m running it here, and I’ve had no problems so far. I’ve still got the cold, but it’s nowhere near as horrible as it was (went to bed at 5pm on New Year’s Eve, woke up at 11am on New Years Day - first time I’ve missed the turning of the year in ages).
Right, we’ve cut a Typo 5 gem and it’s on rubyforge and heading to various mirrors I hope. Frédèric’s writing the release notification which will be appearing on Typosphere Real Soon Now.
It’s been a surprisingly tricky process - we’re now requiring Rails 2.0.2 because the workings of view_paths
have changed in a way which means we can’t quite make themes with Rails 2.0 and 2.0.2 and working with the edge seems like the more sensible proposition. If you’re on the bleeding edge, you should find that you get the right Rails via svn:externals anyway.
So, if you’ve been watching the Typo tree, you’ll see there’s been a fair amount of activity on it since Rails 2.0 got released. There’s a new default theme replacing the rather creaky ‘azure’, and a fair amount of work on getting our code compatible with the current state of Rails. As we work on this, it becomes apparent that Typo’s code is getting horribly brittle. I have said before that there’s been several places where we’ve zigged before Rails zagged, and we’re paying the price for that. It doesn’t help that our test coverage is distinctly ropy either - and I’m probably guiltier than most for letting things get into that state.
Here’s a problem I first came across when I was about 13 and helping do the stock check at the family firm. The parts department kept all their various spare parts racks of parts bins. Each bin was ’numbered’ with an alphanumeric id. We had printouts of all the bin numbers along with their expected contents and we’d go along the racks counting the bins’ contents and checking them off against the print out. What confused me at the time was the way the printouts were organized. Instead of the obvious ordering, “A1, A2, A3, …, A99”, the lists were ordered like “A1, A10, A11, …, A2, A20, A21, …”. After a bit of thought I realised that the computer was sorting the numeric bits of the bin numbers as if they were just sequences of strange letters. A bit more thought made me realise why, post computerisation, people were starting to use bin numbers like “A01, A02, …”. Computers were more important than people so, in order to make sorting things easier, just add spurious leading 0s to make the number field a fixed width and Robert’s your parent’s brother.
Worrying about test coverage when you’re doing Test- or Behaviour-driven development is like worrying about the price of fish in Zimbabwe when you’re flying a kite.
Your tests are there to help you discover your interface and to provide you with an ongoing stream of small bugs to fix. If you write them cleanly, and keep them well factored (you are refactoring your tests, aren’t you?) they will help to document your intent too. Ensuring that every code path is exercised might be intellectually satisfying but that satisfaction costs time, and time is money. And that’s before you start worrying about your code’s malleability. Cover the happy path and the edge cases you know how to deal with and move on. If you’ve screwed something up, it will get found during acceptance testing (or out in the wild) and you can write a few more tests to isolate the problem, fix it, and move on.
Has anyone written an Atompub client in JavaScript yet?
Do you have a PC, Xbox 360 or anything else that will run the Valve Orange Box? If so, get hold of a copy and fire up the Portal subgame.
That is all.
So, we’re doing a cobranding exercise at work. The idea being we serve up a branded version of amazing tunes in a subdomain of our partner, their users get a skinned version of the site that feels like part of the partner’s site, we get an influx of new users and everybody is happy. One aspect of this is we’re using the partner’s site to handle authentication.
Today, we got all our ducks in a row and started authenticating against the partner’s SOAP service as part of our user testing. So off I went to the partner site and set up an account…
Yes, I’ve upgraded to Leopard. Yes, it’s spiffy.
The headline features like Time Machine are great, but I’m loving the little details more.
For instance, the first time you go to run an application that’s been downloaded from the net, a dialogue pops up reminding you that the file has been downloaded and asking if you want to trust it. It’s a nice bit of security, and it asks you the question at the right time.
It’s been a while since I wrote anything here, mostly because I’ve been indecently busy. Well, up until last Sunday when I managed to trip over a low wall in our garden and, in the process take off a large amount of the skin on my left shin. A mere flesh wound, but painful, embarrassing and it’s left me sporting what looks like a foot long, white, elastoplast. The worrying bit is that, when I went to get my wounds dressed, the nurse took one look at my bulk and demanded a urine sample. Which tested positive for glucose. For the second time in a year. So, interspersed with getting my dressings changed at the GP’s, I got a blood test and it looks like I’m diabetic.
Some bugs are easy to overlook. One that has a habit of catching me out is a Rails filter that returns false occasionally when it’s being evaluated purely for its side effects. Here’s how I’ve started working round the issue:
def side\_effect\_filter
return if some\_conditions\_not\_met?
...
ensure
return true
end
What happens here is that the ensure catches any return and returns true instead. The catch is that if something throws an uncaught exception anywhere, it too gets caught by the ensure and true is returned. Which may not be what you were looking for. Here's how to fix that issue:
def side\_effect\_filter
error = nil
return if some\_conditions\_not\_met?
...
rescue Exception => error
ensure
raise error if error
return true
end
This catches the exception in a rescue and stashes it in the `error` variable, then the ensure checks to see if an exception was thrown and rethrows it, otherwise, it just returns true. Which is bulletproof, but ugly. Let's wrap the ugliness up in a method:
def self.side\_effect(method, &block)
def\_method(method) do
error = nil
begin
instance\_eval(&block)
rescue LocalJumpError \# catches an explicit return
rescue Exception => error
ensure
raise error if error
return true
end
end
end
side\_effect :side\_effect\_filter do
return if some\_conditions\_not\_met?
...
end
Again, not pretty inside, but all we actually *care* about anywhere else is that the interface is good and does what it's supposed to do. Encapsulated ugliness has its own beauty. Especially if you get the interface right.
### Homework
This should pluginize quite nicely, just install the method in ActionController::Base and ActiveRecord::Base and you have a very useful tool, but I'm still not sure that the method name is right, so I'm holding off on it. If someone were to come up with a bulletproof name and release a plugin, that would be wonderful though.
### Updates
Fixed a scoping issue in the encapsulated version of the code. Replaced `yield` with `instance_eval(&block)`
Whee! Sat in my home directory is a version of typo that appears to work with Rails 2.0. I ended up giving up on the themer approach which proved to be very hard to get up and running transparently - things kept disappearing off around infinite loops, which is no fun at all, let me tell you.
So, ended up cheating and ended up monkeying with @@view_paths
directly, which is almost certainly against the rules, but has the cardinal virtue of working.
<typo:flickr img=“1455226602” size=“medium” caption=“James Duncan Davidson” />
I’ve finally started uploading the scans from RailsConf Europe last week. There’s still one more roll to scan and another 9 shots in the camera, but I’m pretty pleased with the results so far. I didn’t really start shooting until about halfway through the last day. The light in the hotel was horrible and I just wasn’t in the mood, then suddenly I’d shot three rolls and was wondering where I could find another roll of Neopan 1600 at 9pm in Berlin. It didn’t hurt that I found some really nice light (at least for a black and white photographer with fast film). The shot of James Duncan Davidson above was shot using one of the large LCD screens that were dotted around the hotel as a softlight. It’s the sort of trick that can cause endless pain when you’re shooting in colour, because the white balance is such a bear, but the magic of fast black and white film means I just didn’t have to care.
What does the OED say reticence is?
Reticence: Maintenance of silence; avoidance of saying too much or of speaking freely; disposition to say little.
Pretty straightforward. When I chose reticence as one of my five nouns for programmers it was another reminder that objects are not the same as datastructures. Well designed objects keep their cards (instance variables) close to their chest. Client code tells objects what to do, it doesn’t ask them to kiss and tell. In Smalltalk Best Practice Patterns, (you don’t have a copy yet? Are you mad?) Kent Beck recommends that you put your accessor methods in the private
protocol unless you have a very good reason for indicating that the accessors should be used by clients by putting the accessors in, say, the accessing
protocol or some other, more suitably named, protocol. (In Smalltalk, all methods are public, but you can and should organize them into protocols/categories, either by choosing some existing protocol, or coming up with a new protocol name). In less flexible OO languages, you should probably at least mark your accessors as protected unless you have the aforementioned very good reason.
Britt Selvitelle of Twitter gave a cracking talk at RailsConf Europe about scaling Rails applications to Twitter scale. It was great. Full of advice that we shall definitely be taking on board as we continue to develop amazing tunes. However, the last slide before the inevitable “Any Questions?” was the slide of the conference. It read:
It’s 2007. Every spammer has your email address. Put it on your goddamn webpage so people can get ahold of you about interesting things
During DHH’s keynote at RailsConf Europe it was apparent that there’s a great deal to like in edge rails, so I thought I’d have a crack at getting Typo up on it.
Ow.
I’d expected the pain points to be related to routing, but it seems that the rails routing system is approaching the level of the Excel calculation engine - nobody dares touch it for fear of breaking things, so typo’s custom routes seemed to work quite happily. There were a few things that have been deprecated, pluginized or moved out of the set of modules that’s automatically included when you do a rake rails:freeze:edge
, but they were pretty easy to sort - the deprecation messages are a good deal more informative now than they were last time went deprecation squashing. There’s a surprising amount of stuff that’s been removed without any deprecation warnings though, which isn’t very sporting. DHH said there would likely be a 1.2.4 release (possibly a day before 2.0) with a bunch more deprecation warnings covering everything that’s actually going away, so if you’re thinking of moving a maturish app to Rails 2.0 it might make sense to wait for 1.2.4, install that, squash warnings, and move on up to 2.0.
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. I’ve managed to cover the last couple of O’Reilly European conferences in a timely fashion without having to go digital and I don’t want to break that record.