Kurt Schrader
My new law of Ruby complexity:
For a Ruby application increasing in size at rate of X, with an amount of cleverness to cover up the complexity increasing at rate Y, the quantity Y is always greater than X, and Y eventually approaches positive infinity.
Working on Ruby projects has given me enough examples of "Where did that method come from?" to last a lifetime.
Kurt Schrader
(Or, How I Spent My Martin Luther King Day Weekend)
Here are the web app frameworks I've been reading about and playing with for the last few days. As usual, they've got a bunch of cool ideas that we'll be seeing in mainstream frameworks in 4 or 5 years.
Weblocks: Weblocks is a continuations-based web framework written in Common Lisp. Think Seaside, in Lisp.
Ramaze: An MVC framework written in Ruby. Like Rails without all of the garbage and magic.
Check them out. Pretty cool stuff going on.
Kurt Schrader
For the last twelve years I've been building web applications. During that entire time I haven't ever worked at a software company that hasn't, at one time or another, been concerned with prematurely optimizing the application we've been working on.
I think that we can all learn an important lesson from this study of gym users that was recently written up in the Financial Times (via Paul Kedrosky).
Two Californian academics, Stefano DellaVigna and Ulrike Malmendier, studied three US health clubs and discovered that 80 per cent of members used the gym so infrequently that they would have been better off paying the $10 fee for each individual visit. Many also left substantial gaps between their last visit and cancelling their membership.
This tracks well with my experience with subscription based software products. People inevitably sign up for more access than they need, and the difference between what they pay to use and what they actually use ends up going straight to your bottom line. Optimizing for expected usage never really pays off, because usage never lives up to expectations.
Also, get people on an auto-renew plan:
Some clubs attempt to limit the attrition rate by telephoning inactive members and asking whether there is anything the club can do for them. Mr Ratner never thought this was a good idea as it might remind them that they were wasting their money.
Lesson: People almost always use your software less then they, or you, expect. This is a good thing (for you, perhaps not so much for them).
Kurt Schrader
Last Thursday I published a couple of blog entries and the next thing I knew my FeedBurner stats looked like this:

So I figured I'd ask the lazyweb. Anyone ever seen anything like this before? Is FeedBlitz just spamming my RSS feed?
Kurt Schrader
Today marks the official beta launch of Triggit, the tech side of which is run by my friend Ryan Tecco (who co-founded Ten Ton Labs with me a few years ago).
So what's a Triggit? It's an easy way to insert images, videos, or text links into your blog, without downloading or installing any software.
All you have to do is add one line of code to your blogging software template. You can then use a cool Javascript based tool to insert objects into your blog on the fly. As you can see in the picture below, the Triggit interface just overlays itself on the top of your site to allow you to insert things:

You just select what type of object you want to insert and then drop it into the page wherever you want. For instance, I've used Triggit to insert this image, of Ryan dressed like a cow from Halloween a few years ago, into this post by searching for it on Flickr through their interface, and simply dropping it in below:
This is a game-changing sort of tool that will make your life as a blogger much easier. If anyone wants to try it out, I have 300 invite codes to the beta to hand out. Just use the access code 'kurt' when you sign up.
Update: More coverage at TechCrunch , GigaOm, and WebWare.
Kurt Schrader
My coworker Krishna, inspired by Giles Bowkett's post Rails Debugger: Use RCov With Selenium, Watir, Or Just In Real Life, whipped up a little rake task that automates the process of checking code coverage using your Selenium tests:
desc "Measure coverage of selenium specs"
task :coverage do
FileUtils.rm_rf "selenium_coverage"
mongrel_pid = fork { exec("rcov script/server -o selenium_coverage --rails -- -e test -p 4000") }
sleep(6) # wait for mongrel to start
begin # selenium will call "exit 1" if there are failures
Rake::Task["selenium:spec"].invoke
rescue SystemExit; end
Process.kill("INT", mongrel_pid) # triggers generation of rcov report
Process.wait
system("open selenium_coverage/index.html") if PLATFORM['darwin']
end
While we don't agree that this task, in any way, shape, or form, constitutes a debugger, it has been useful in showing us areas of our code base that our Selenium test cases aren't hitting.
This should work for just about anyone that has a rake task to run their Selenium (or Watir, or other in-browser testing tool) tests. Just replace 'selenium:spec' in the block above with whatever task you use to run your in browser functional tests and have at it.
Kurt Schrader
Wow:
MacBook Air is 0.16" to 0.76"
There must have been some amazing engineering that went into that thing. I'm already drooling over it. I'm assuming that we'll see more info at http://www.apple.com/macbookair/ soon.
Simon Harris
I'm pretty sure I've blogged before about my dislike of prefix/suffix pairs such as from/to and start/end. They smell of a missing abstraction. There are however languages that provide a nice solution.
We have an application that stores a date against a record in the database. At various times, we want to see if that date falls between a specific date range. The initial implementation of the code looked something like this:
def within?(from_date, to_date)
@date >= from && @date <= to
end
Which you would then be used along the lines of:
puts "Not available" if record.within?(start_date, end_date)
This immediately activated my olfactory senses: Not only do we have some common suffixes, we also have comparison code that looks like pretty much like every other kind of range comparison code you're ever likely to write.
As it happens, Ruby has a Range class built-in that I don't see being used nearly as much as I think it deserves. Using a range we could re-write the example to look something like:
def within?(date_range)
date_range.includes?(@date)
end
And then in the worst case, call it like this:
puts "Not available" if record.within?(start_date..end_date)
I say worst case because here the client code still uses two separate dates which are then converted to a Range for the purposes of the call. (Interestingly the use of use of .. to construct a Range out of two individual values uses the same number of keystrokes as passing the parameters individually!) However, in the best case, we'd have been using a Range to store the dates in the first place.
Simon Harris
FWIW, I've just created two very new, very simple and VERY BETA Rails plugins.
The first, Simian, is pretty obvious: it adds a couple of rake tasks to run duplicate code checks against your rails project using, you guess it, simian.
The second is Restful Transactions. This plugin ensures that your controller's create, update and destroy actions are wrapped in a database transaction meaning you don't have to think about it.
As always, you'll find these plugins and more over at the RedHill on Rails plugin page
Paul R. Brown
I've switched my publishing engine from Typo to a home-brew
platform called "perpubplat" which appears to be stable enough (i.e.,
better than Typo) but will remain a work in progress. (I'll post more
on perpubplat later; I'm happy to share source code with folks and
will post Darcs repository information
once I've cleaned things up a bit.)
Of relevance to feed subscribers (and perhaps how you ended up
here):
- RSS feeds
are no longer provided in any form. What would have been a request
for an RSS feed directs to an Atom feed containing this post.
- As a corollary of the non-existence of RSS, categories
(as semantic artifacts of RSS) no longer exist. Instead, you can pick
out a relevant by-tag feed, e.g., for posts tagged Haskell, Java, or entrepreneurship.
(For any by-tag or by-date view, there is an associated feed available
via autodiscovery.
- Comment feeds by article internal identifier are no longer
supported. (Comment feeds by article are supported with a different,
permatitle-based URI; check the autodiscovery links on a single
article page.)
Of relevance to visitors:
- For the time being, new comments aren't supported directly on this
blog, but that shouldn't stop you from commenting on your own blog or
posting to a community site like Reddit or DZone. The plumbing for
comments (as well as trackbacks and backreferences) is present, but I haven't decided how I want to restrict
content and control spam yet. Historical comments and trackbacks
are present.
- I've made some effort (i.e., using FeedValidator and
xmllint)
to ensure that specification compliance is provided when advertised,
including cleaning up the content of older posts, but please let me know if something falls
short.