-
"The tests are the program. Without the tests, the program does not work. Tests are not something that should be left for the inexperienced; tests are the hard part."
-
"The analysis presented here explores word usage in the 2008 US Presidential and Vice-Presidential debates. The purpose is to explore the structure of speech, as characterized by the use of nouns, verbs, adjectives and adverbs, and noun phrases. The speech patterns of opposing candidates are compared in an effort to identify characteristic value and personality traits."
-
"How I asked my GF to marry me in Little Big Planet. My (now) Fiancee was playing the level. She was so shocked she kept playing and knew i was filming. Afterwords we hugged, she cried, and I gave her an engagement ring." This is amazing in so many ways, not least of which that she wasn't the first person to paly it.
-
"The suits took issue with every brave, authority-questioning page of our Meet the Sandvich script-specifically that there were supposed "similarities" between it and the 1987 action film Predator, and more specifically that it was word for word the 1987 action film Predator."
-
"Each issue of this unique title is 3,840 half-inch-square panels of nothing but dots talking to each other. The concept is that everyone is drawn so far away that all you can see is a dot. And the dots do stuff. Like smack each other, or give birth, or die. It’s brilliant, it’s hilarious, and it’s mind-blowing."
-
"People think the interface is the game, and I think that is kind of backwards. I think the game is the game, and we should be thinking what are the many interfaces to it… you touch Twitter in many ways, you touch Facebook in many ways." Raph Koster. But you guessed that, right?
-
Wonderful.
-
"There's a weird conceit in here, that the activities and practices of normal human beings will involve data processing and algorithms of some sort, which is an awfully big assumption. So big, in fact, that it has distilled down to a way of seeing the world as consisting of bits of data that can be processed into information that then will naturally yield some value to people… Design for people, practices and interaction rituals before the assumptions about computation, data structures and algorithms get bolted onto normal human interaction rituals."
-
"Recently I had been wondering what the complete list of HTTP status code symbols was in Rails. Searching through Rails didn't yield any results for a symbol like :unprocessable_entity… Rails defines the symbol to status code mapping dynamically from the status message. The symbol used is an underscored version of the status message with no spaces." Quick list of clear textual shorthand for returning HTTP status.
-
"Let’s no longer think in terms of selling them a game. Let’s instead think of selling them an experience." A nice article on the changing shape of game design, particularly when it comes to narrative and participatory hooks.
-
"These concepts are not complicated by Cern standards. We are entering a zone which is weaponised to boggle."
-
Simple, straightforward, pretty much correct.
-
Yes, this is going to come in handy.
-
"This javascript function can then read in the current content of the text area, format it using a trimmed down version of textile, and then set the content of a DIV with the resulting HTML. The end result of all this is live comment preview, with textile formatting." Live textile preview functionality.
-
"Trying to over-explain the cause of a disaster often detracts from its more tangible impact. … Instead, Faliszek says, it is more effective to create resonant gameplay experiences that players will remember, particularly if the setting in question, such as a zombie invasion (or a tornado outbreak, for that matter) is already familiar." Why games don't always need tangible villains.
-
A nice approach to doing some of the typical monitoring you'd want to do with Google Analytics, eg monitoring PDF downloads. I'm not totally convinced by some of his syntax, but the functionality is good, and the regex trick is nice.
-
"It's just an Nintendo in a toaster, but I like it."
-
A strong article from Joe on some guidelines, based on experience, for writing RSpec user stories.
-
Getting around the issues with Rails' authenticity tokens and trying to perform Ajax requests in jQuery.
-
"I think this is very important. If we limit ourselves to only designing the present then the ‘future’ will just happen to us, and the one we get will be driven by technology and economics. We need to develop ways of speculating that are grounded in fact yet engage the imagination and allow us to debate different possible futures before they happen." Interesting interview with Dunne over at the Adobe site.
-
Fingerboarding game for the iPod; really delightful, and clearly a fun thing to do with your fingers. Also: it makes sense to play this with the device on a flat surface, which is unusual for the iPod games released to date.
-
"The winner is Tim Graham who took manual personal data collection to another level. From email spam, to beverage consumption, to aches and pains, Tim embraced the spirit of self-surveillance. He even made his personal data available in the forums." Dataviz overload!
-
"What are the weird, seemingly unimportant data that can join up the areas we already know, and how do we know where to look for it? In order to be truly useful eyes on the street, we need to be able to take the scenic route, or shortcuts, or any other route that will be fun or illuminating for us and the people we speak to."
-
"With a recent project, we really started utilizing extensions with named_scope which is very powerful and cleaned up our code considerably." Some really nice examples of using named_scope effectively.
-
"Nintendo makes money with the hardware alone, which may be a superior business model." What, making profit on units rather than selling them at colossal loss is a *superior* business model? Who would have thought it!
-
Long thread of patched and hacked 8-bit and 16-bit ROMs, some bringing a vast amount of customisation.
Connecting Rails to legacy databases
01 November 2007
Connecting Rails to legacy databases isn’t actually that hard – depending on the database you start out with. Recently, we needed to perform some statistical analysis on a large Movable Type database. Rather than wrestling with endless SQL queries at the prompt, it made sense to abstract out a little and build some kind of modelled front end to the statistics.
The most obvious tool for me to use was Rails; I’m familiar with it, I like the way ActiveRecord works, and it means that I can poke around the database from script/console
if I need to.
The reason this turned out not to be too hard is because whilst Movable Type doesn’t conform to Rails’ opinionated ideas of what a schema should look like, it is still a well-designed and normalised database. Because of this, we can teach ActiveRecord to understand the database.
First of all, we start by creating our models: for our needs, Blog, Comment, Post and Author. We generate them in the usual manner – script/generate model blog
. Once we’ve done that, we delete the migration files in db/migrate
it creates, because we’re not going to use them.
Next, we point config/database.yml
to the Movable Type database.
And then, we build our relationships thus:
class Blog < ActiveRecord::Base
set_table_name "mt_blog"
set_primary_key "blog_id"
has_many :entries, :foreign_key => "entry_blog_id", :order => "entry_created_on"
end
class Entry < ActiveRecord::Base
set_table_name "mt_entry"
set_primary_key "entry_id"
has_many :comments, :foreign_key => "comment_entry_id"
belongs_to :blog, :foreign_key => "entry_blog_id"
belongs_to :author, :foreign_key => "entry_author_id"
end
class Comment < ActiveRecord::Base
set_table_name "mt_comment"
set_primary_key "comment_id"
belongs_to :entry, :foreign_key => "comment_entry_id"
end
class Author < ActiveRecord::Base
set_table_name "mt_author"
set_primary_key "author_id"
has_many :entries, :foreign_key => "entry_author_id"
end
The set_table_name
method tells the ActiveRecord class what table to look at, and the set_primary_key
method does exactly what it says on the tin. (It also makes sure that #to_param works correctly based on whatever our new primary key is, which is handy). Beyond that, we simply have to specify the foreign keys on our relationships and everything plays ball; we can now access blog.entries
just as we do with a typical Rails setup. It’s now easy to write the rest of our Rails app – model methods, controllers, views – just as we normally would. We’re just using the MT database to pull out our data.
And if you’re wondering: yes, it made the manipulation a lot easier, and a few hours poking at the console began to yield some interesting algorithms to apply.
Pimping my iTerm: the TextMate edition
24 July 2007
Rob Orsini’s got a nice little shell script for opening iTerm with everything he needs for his app: a vim window or two, a dev server, the Rails console, and a final tab to tail the development logs.
Of course, I’m a TextMate man myself, and so a bit of tweaking this morning brought out my own version of it. The first tab opens the project in Textmate and puts your shell into the project root, all ready for running tests and specs (unless you’ve already caught the autotest
bug); the second tab fires up Mongrel on port 3000; the third fires up the console; the fourth tails development.log . The changes in filenames/commands are mainly my personal environment, so tweak away. Hardly warrants a blogpost, really, but thought I’d share, because it’s really going to be useful in future. Requires iTerm, TextMate, and the mate
command (which should be set up by default when you install TextMate).
#!/bin/sh
if [[ $# == 0 ]]; then
PROJECT_DIR=$PWD
elif [[ $# == 1 && -d "$1" ]]; then
PROJECT_DIR="$@"
else
print "usage: railsterm.sh [rails project directory]"
return 1
fi
osascript <<-eof
tell application "iTerm"
make new terminal
tell the last terminal
activate current session
launch session "Default Session"
tell the last session
set name to "$PROJECT_DIR"
write text "cd \"$PROJECT_DIR\""
write text "mate .;"
write text "clear; ls;"
end tell
launch session "Default Session"
tell the last session
set name to "server"
write text "cd \"$PROJECT_DIR\""
write text "mongrel_rails start"
end tell
launch session "Default Session"
tell the last session
set name to "console"
write text "cd \"$PROJECT_DIR\""
write text "./script/console"
end tell
launch session "Default Session"
tell the last session
set name to "development log"
write text "cd \"$PROJECT_DIR\""
write text "cd log"
write text "tail -f development.log"
end tell
end tell
end tell
eof
Don't forget to chmod +x
the file if you want to make it executable.
I’ve just had my first patch accepted on an open source project. Quite chuffed with that! As of this weekend, the Rails calendar_helper
plugin is now at version 0.21. My changes are very minimal, and only really to do with the markup.
Firstly, the default table markup’s had an overhaul. The date now goes into a %lt;caption>
tag, outside the <thead>
, as is appropriate. The <th>
‘s in the thead
now have scope="col"
applied to them, again, as is appropriate.
The only other change is optional. If you pass in an option of :accessible => true
, any dates in the grid which fall outside the current month will have <span> class="hidden"> monthName</span>
appended to them. It could be reasonably inferred that plain numbers are dates that relate to the caption of the table, but the numbers outside the current month should probably be clarified.
You can come up with your own method of hiding content marked as .hidden
; at NPG, we use the following:
.hidden {
position:absolute;
left:0px;
top:-500px;
width:1px;
height:1px;
overflow:hidden;
}
but really, use whatever you’re most comfortable with.
You can get the plugin from Geoffrey Grosenbach’s subversion:
http://topfunky.net/svn/plugins/calendar_helper/
via the usual Rails plugin installation method.
(I wasted about half an hour on this last night, and am now kicking myself about how simple it was. Given that… definitely worth documenting the problem, so that no-one else gets held up on it.)
I’m currently working on some forum software (before you yawn: it’s not your average forum, it’s not worth the effort forking Beast, and besides, it’s a learning exercise). In this forum, when you create a topic, you also create the first post in the topic at the same time. Here’s how that happens (I don’t think I need to show the form view – the controller will suffice):
@topic = Topic.new params[:topic].merge(:user => current_user, :forum => Forum.find(params[:id])) post = @topic.posts.build(params[:post].merge(:user => current_user))
Unfortunately, I was running into all sorts of problems – in that even though the forms were filled out and being passed to the controller, the topic wasn’t being created. This was because the post wasn’t validating. Turns out the problem was that in my post.rb
, I’d said that a Post validates_presence_of :topic_id
. This validation was clearly being run before the topic was created; given we’re using build
to make sure the post is attached to the topic, I don’t think we need that validation. Once I stripped that out, everything worked fine.
A pretty trivial error, I know, but once my tests started failing, I had to take the application apart a little to find out what was going on. In a nutshell: I don’t think you always need to validate relationships that have to exist for the model to make any sense.
Of course, if there’s a way I can keep the validation of topic present but still build
the topic/post combination as above… comments are very welcome.
0 errors, 0 failures
13 January 2007
I wrote my first proper Unit Tests in Ruby today. It felt good.
That probably sounds slightly gauche and hypocritical coming from a Rails developer. But remember – I’ve come from a front-end background; most of the time, other people make the tests; it’s up to me not to break them. I’m perfectly capable of editing tests to bring them in line with updated functionality; it just tends to have been the case that I’ve never really got my head around testing properly.
That changed recently, mainly thanks to Geoffrey Grosenbach’s excellent Peepcode screencasts. I’ve read a fair amount on testing up to now – Mark Pilgrim’s Dive Into Python is very good on the subject – but it was Geoffrey’s material that really clicked with me. (I’m watching his Capistrano one at the moment, and it’s certainly proving to be as good as the testing one).
I’ve always understood the point – and the utility – of test suites, but I’m pleased to have got my head around writing my own, starting with one (of several) projects on the back burner. Small steps at first, but it’s really satisfying to be working in a relatively test-driven manner.
And so I’ve been enjoying watching the dots fly by before those magic words come up: 0 errors, 0 failures
. The Peepcode screencasts come strongly recommended, as well. Here’s to slightly more watertight code from now on.