7 days ago
I 'm pissed off about this:
O2 Ireland and iPhone upgrades before an upgrade is due
Strict rules around phone upgrades have never really bothered me in the past, as I'm usually due an upgrade around the time I go looking for a new phone.
Not so with the iPhone on O2 Ireland. I started a thread on their "discussion" forum and after initially being shot down by "support" staff, the thread got some good replies, particularly in relation to just how many operational "rules" a customer must "break" just to get an iPhone at all.
10 days ago
I think Leo has the right idea about this:
Everyone thinks of changing the world, but no one thinks of changing himself/herself.
Leo Tolstoy
26 days ago
I wrote this:
Rails plugin: Accepting "http://" or not on a URL field
Sometimes, you have a field on an ActiveRecord Rails model that stores a URL. The user might enter "http://" or they might not. I had this problem, solved it for one model, then needed it for another one. It's plugin baby time!
So I made the world's simplest URL field plugin
Just throw the "url_field" into your class:
class Company
url_field :website
end
@company = Company.new
@company.website = "www.example.com"
@company.save
@company.website #=> "http://www.example.com"
Available now, free on Github
Update: Des and James were quick to point out that my initial release would incorrectly add "http://" to "https://" URLs. Quick patch!
29 days ago
I like this:
Flaming Lips — Do you Realize??
Do You Realize - that you have the most beautiful face Do You Realize - we're floating in space - Do You Realize - that happiness makes you cry Do You Realize - that everyone you know someday will die
And instead of saying all of your goodbyes - let them know You realize that life goes fast It's hard to make the good things last You realize the sun doesn't go down It's just an illusion caused by the world spinning round
about 1 month ago
I shiver at this:
Most people are other people. Their thoughts are someone else's opinions, their lives a mimicry, their passions a quotation.
Oscar Wilde
about 1 month ago
I enjoyed reading this:
Virtues of good CEOs
www.nytimes.com/2009/05/19/opinion/19brooks.html
"In 2001, Jim Collins published a best-selling study called “Good to Great.” He found that the best C.E.O.’s were not the flamboyant visionaries. They were humble, self-effacing, diligent and resolute souls who found one thing they were really good at and did it over and over again."
Find one thing you're good at and do it over and over again. The one true path to success?
about 1 month ago
I believe this:
Beware of the barrenness of a busy life.
Socrates
2 months ago
I pondered this:
Life is an experience of ripening. The green fruit has but small resemblance to that which is matured.
Charles B. Newcomb
2 months ago
I 'm free to post this:
"Freedom is the right to be wrong, not the right to do wrong."
John George Diefenbaker, (1895 – 1979), a criminal defence lawyer, was the 13th Prime Minister of Canada.
2 months ago
I 'm in awe of this:
Pet Sounds — A Capella
naturalismo.wordpress.com/2009/04/22/pet-sounds-acapella/
Pet Sounds with all the orchestration removed. Just the vocals. Shows just how good the songs were before Brian Wilson got into the producer's seat.
2 months ago
I read and enjoyed this:
Why Programmers Suck at CSS Design
www.betaversion.org/~stefano/linotype/news/169/
Long, interesting and useful piece chock full of tips to help developers make their work a bit more palatable to humans
2 months ago
I took a deep breath, then read this:
There was never yet an uninteresting life. Such a thing is an impossibility. Inside of the dullest exterior there is a drama, a comedy, and a tragedy.
Mark Twain
2 months ago
I laughed when I passed this:
This is about five or six doors down from where I live. He's since been removed from service!
2 months ago
I enjoyed reading this:
Chad Fowler's survey of Rails Development no-no's
www.chadfowler.com/2009/4/1/20-rails-development-no-no-s
Maintaining best practices is hard, but it helps to look at it in the context of the smells you leave behind when you don't adhere to them.
I particularly like the format of putting out a tweet and bringing them together in a blog post.
2 months ago
I am going to this:
Huge names on the web coming to Belfast
Eric Meyer, Wilson Miner, Ryan Sims, Tim Van Damme, Andy Budd and Sam Brown, coming to Belfast in November. Andy McMillan is definitely one to watch.
3 months ago
I came up with this:
My personal coding guidelines for where to put stuff in Rails ActiveRecord models
While working with Rails ActiveRecord models recently, I've found that I'm never sure where to put things. Should validations go before relationships? Should class methods come before instance methods? I've started keeping a coding guideline for myself to keep things nice and consistent. It doesn't follow much of a rational order, but it's something, and I've gone with my gut and my gut is happy. Here's what I've come up with:
- includes
- validations
- called class methods
- relationships
- callbacks
- named scopes
- class method definitions
- public method definitions
- private method definitions
- callback method definitions
So, for example, here's how a Post class would look:
class Post < ActiveRecord::Base
# includes
include SpecialPostMethods
# validations
validates_presence_of :title
validates_uniqueness_of :slug
# called class methods
acts_as_textiled :body
# relationships
belongs_to :site
has_many :comments
# callbacks
after_create :save_slug
after_save :ping_technorati
# named scopes
named_scope :most_popular, :order => 'votes DESC'
# class method definitions
def self.post_types
['post', 'page']
end
# public method definitions
def permalink
...
end
private
# private method definitions
def flush_cache_entry
...
end
# callback method definitions
def ping_technorati
...
end
end
Your mileage may vary with this, but I've found that it's really helped me not have to think about where I'm putting stuff. Everything now has a place, so I know I can consistently put things where they should be, or tidy things up when I'm using old code.
3 months ago
I thought about this:
Dave Winer and ideas
I like catching up on Dave Winer's blog every so often. It's definitely a whole lot more than scripting news.
I like his thoughts on ideas in snowstorms ... the kind of moments I guess that James Webb Young promotes in "A technique for producing ideas" ... the snow storm (or whatever) jolts the subconcious mind to look at old ideas in a new light.
I also like the idea of Digg for ads ... I love being advertised to when a) it's a really exciting ad and/or b) I really want the product. I really hate it when a) The ad is awesome but it's some crummy product like fat-free yoghurt or b) it's some crappy thing and it's on the TV because the guy's cousin knew the station manager and a bit of Final Cut pro.
I also hate those crappy musical Halifax ads.
3 months ago
I felt ill reading this:
Nightmare killing
news.yahoo.com/s/ap/20090329/ap_on_re_us/birthday_killings
Terrifying to think that this is real life, that it's probably just a cross-section of what's out there.
3 months ago
I melted to this:
Nouvelle Vague — I'll melt with you
Your whole world could be falling down around you and you'd have a hard time not living up to the title of this song.
3 months ago
I laughed out loud at this:
Phallic rooftop
news.bbc.co.uk/newsbeat/hi/newsbeat/newsid_7961000/7961224.stm
I like how they don't mention anything about what the drawing is in the caption.
3 months ago
I chuckled at this:
"Automated testing is the warmest blanket for an OCD person that you could possibly wrap yourself in"
Hampton Hates Automated Testing from Hampton Catlin on Vimeo.
I don't necessarily agree with this, but I do believe that one should always have a good healthy balance in life! My stance is that testing code is one of many disciplines to help you reflect on the work that you've done. As well as the obvious benefit of helping you out when you break stuff later!
My favourite comment: "whoa, your hair! obviously i have nothing productive to say about automated testing. ps. nice shirt!"
3 months ago
I coded some of this:
Using Twitter's API to sort friends / followers alphabetically
One of the reasons I set up this tumble-loggy blog, rather than stick with a regular blog, was so that I could share little snippets of code every so often, related to the stuff I was working on.
That's why I was delighted when Jon Crawford (NewMonarch) on Twitter asked me this:
I need to grab a Twitter user’s followers on the fly. As you probably know, the friends list isn’t returned in alphabetical order. Instead it’s returned in the order of which you started following the user, 100 results as a time. I’d prefer that the results were returned in alphabetical order by screen_name.
I like this kind of request, because it's one I know the answers to!
Since the beginning, Twitter has provided friends / followers methods for getting a list of a Twitter user's friends or followers. These methods have been damned to hell though, because they only report back 100 users at a time. Worse, they send back all manner of extra data, such as the latest tweet and in depth profile information. This meant for a lot of wasteful traffic back and forth to the API, and crucially lots of requests, eating up your API limit.
This was a particular bone of contention for an app like Qwitter. For someone like Gary Vaynerchuk for example, with tens of thousands of followers, we'd have to make hundreds of requests to the api just to get a list of Twitter follower IDs. A fun programming exercise, no doubt, but seriously inefficient.
At the beginning of February, Twitter released two methods that mark a change in the game for Twitter API developers: their social graph methods
Essentially, these methods let you download an entire friends list or followers list in a single API call:
curl http://twitter.com/friends/ids.xml?user_id=1401881
It just returns a list of IDs, but it's massively more efficient than making lots and lots of calls to the API, particularly for Qwitter.
For Jon Crawford's problem, it marks the beginnings of a solution. Because Qwitter compares the differences in two lists of IDs, we don't rely on associating usernames with IDs.
Here's a script that returns an array of friends sorted in alphabetical order. I've used John Nunemaker's excellent Twitter gem.
The big problem with this script is that it's actually more inefficient than paging through 100 followers at a time, as it makes one API request per user. Perhaps for the first run of a user, something like this would be better:
Then keep a cache of usernames and associate them later. It all really depends on your needs.
3 months ago
I love it when I remember this:
Múm — Smell Memory (live clip on Youtube)
This occassionally pops in to my head and makes me smile. I love the simplicity but also the harshness of the melody.
3 months ago
I don't know what to think of this:
Giant Tetris (or tiny Tetris)
sovietrussia.org/f/src/tetoris.swf
It took me 5 minutes to get an eighth of the way across. Fun though!
3 months ago
I developed this:
My screencasting flow
I've been using Screenflow for the last few days to do some screen casts for a client. It's pretty good. Not perfect, but neater than Snapz Pro X.
I developed a pretty good flow, which I'd like to share. One thing I can't emphasise enough is the need to write a script. I tried doing voiceover and actions at the same time and it just ended up a mess trying to type and talk convincingly at the same time. Here's the flow:
- Write a script based on the client's requirements. Guess at how long the action will be on screen to decide on how wordy each explanation should be.
- Do the screen capture video with the script on screen. I kept mine in a narrow window along the right side of my screen. I glance at the script while I record the actions, trying to hear myself saying the words in my head, to keep pace.
- Save the video and record the voiceover on a new track. In Screenflow, you can hit Apple-Shift-R to add a recording. You have to manually hit play on the controls to play back the 'cast.
- You might need to tweak the script if it doesn't quite match the video. Try and keep the pace smooth, but don't be afraid of a gap every now and again.
- Rinse and repeat
I can't emphasise enough how important it is to have a script. I'm constantly tweaking, tweaking, making sure the words are just right.
This flow would probably make a good screencast itself. I might do that some time. It would also make for a very neat presentation. *Adding to my list*
3 months ago
I wish I could persuade more people about this:
"It’s entirely your responsibility to make your dreams come through."
3 months ago
I wrote this:
Talks I'd like to give
This last week has been very conference heavy, but it's also been an indicator to me that there's lots of stuff inside my head that people could probably make use of. I'd be really interested in speaking more about my experiences with:
- CouchDB - I've dabbled a good bit and released Stuffing
- Amazon Web Services (particularly EC2 + EBS, S3 and SQS) - Lots of experience building and scaling Exceptional
- Customer service - I've manned the feedback email for Exceptional since we launched
The list is really for my own reference, but if you'd like to hear my thoughts on these, get in touch!
3 months ago
I presented this:
My Twitter API talk
I gave a talk last Wednesday at "API wars", a Web2Ireland event on APIs before the Facebook Developer Garage. It seemed to go down very well. I think the whole thing was filmed, so hopefully all the talks will be available online. It was my first talk in front of a sizeable audience and it went very well. My green-on-black Terminal screenshots didn't appear on the big screens, so with apologies to _Why, I left the stage to show the crowd how the Ruby Twitter gem works. A lot of fun.
I've made the slides available as a PDF.
4 months ago
I am delighted to discover this:
Twitter social graph methods
Twitter's social graph methods, launched last month, are the secret sauce behind Qwitter. Up until yesterday, when I implemented these methods in the app, I had been mocking them by using round robin to loop over the many thousands of Qwitter users, paginating through hoards of data just to extract the user IDs of followers.
Now I can get all the user IDs of someone's followers in just a single API call.
This is big news not only for Qwitter, but for any app that is doing things with followers lists. No more are we restricted to the 100 per page limit that was imposed before ( plus the unecessary bloat of getting latest status, screen name etc.
The good news is that I can now say that Qwitter should be able to maintain a decent bit of reliability, at least up until around 250k users. We're not quite there yet.
4 months ago
I agree with this:
"The best plan is to overload Google with a long tail of good stuff and to always act as if you're on Candid Camera, because you are."
4 months ago
I chuckled at this:
"If not actually disgruntled, he was far from being gruntled."
P. G. Wodehouse
4 months ago
I wrote this:
Good writeups for projects I'm involved in
Two writeups in a week, awesome. Exceptional was featured in Smashing Magazine's 10 Useful tips for Rails Developers ... we got a really nice big screen plastered on the "Track application exceptions" section.
Also, to my delight, Stuffing is featured on Rails Inside. Proud to see my little experiment get attention. I think that CouchDB really is the next big thing.
4 months ago
I feel obliged to admit this:
I swam a half-mile!
As it turns out, my maths suck. I was informed yesterday that a mile is actually 64 lengths, not the 32 that I achieved... I was basing my figures on the pool being 50m in length, not 25m.
Still, I was actually happy enough to learn that, as the point of my post was less that I swam a mile and more that a definite goal is more easily achieved. I now have a new definite goal: 64 lengths. A mile!
4 months ago
I wrote this:
I swam a mile
I started swimming a couple weeks ago as a way of relaxing / keeping fit in the morning. I've been going in about a half hour before I start working, so I only fit about 10 lengths in. Today I got in a bit earlier and when I got to 15, I realised that I'd swum about 750m. I realised that hey ... I could get to a thousand, and if I really wanted to, I could probably get up to 1.6k - the elusive mile! Well, it's surprising how easy those next 17 lengths came to me once I had that goal. A mile! There was something exciting about that last length, legs flailing, arms all over that place. Exciting, rewarding. A mile!
4 months ago
I enjoyed this:
Louis CK on Conan
www.youtube.com/watch?v=LoGYx35ypus
A client recommended this after a long day's work. Louis CK on counting your blessings ... "Maybe we need some time where we're walking around with a donkey with pots clanging on the sides"
4 months ago
I firmly believe, but don't often enough abide by this:
"In matters of style, swim with the current; in matters of principle, stand like a rock."
Thomas Jefferson, 3rd president of US (1743 - 1826)
4 months ago
I was amused by this:
Neat preview of new U2 album on irishtimes.com
Apparently one of the songs that I've been working on with some mates is very similar to one of these. Dang!
4 months ago
I played with this:
Google web history
www.google.com/history/trends?all=month&hl=en
Extraordinarily responsive breakdown of your own personal Google usage. Eerie, but useful!
4 months ago
I was shocked to find this:
The UK Companies House company search shuts down after midnight. Doesn't this kind of miss the point of the internet?
4 months ago
I was interesested to read this:
Dan Benjamin on why avatars matter
http://hivelogic.com/articles/2009/02/why-your-avatar-matters
Some good insight from one of the smartest guys on the web
4 months ago
I appreciated this:
Handy sample Rails app with YUI uploader
cameronyule.com/2008/10/rails-2-1-yui-uploader-example
So getting the Yahoo YUI uploader to work with Rails is a bit like voodoo. Cameron has published a concrete example using jQuery as well as YUI that works right out of the box.
4 months ago
I loved this:
The Pirate Bay legal story
blog.wired.com/27bstroke6/2009/02/pirate_wednesda.html
A description of the courtroom proceedings of the legal case against The Pirate Bay. A riveting, exciting read, an irony-fuelled good vs. evil battle
4 months ago
I like the look of this:
YUI Uploader
developer.yahoo.com/yui/uploader
The YUI uploader is an open source extraction used in the Flickr web-based uploader. Cool stuff, and in theory more reliable than SWFUpload if it's in production use on Flickr.
4 months ago
I shared this:
'fd' tab trigger in TextMate for creating new Rails form fields
In my screencast below, I used an 'fd' tab trigger in Textmate to generate a div containing a field and a label. This isn't part of the Rails Textmate bundle. Here's the code to generate a label and field inside a div:
<div> ${RAILS_TEMPLATE_START_RUBY_EXPR}f.label :${1:attribute}${2:, "${3:${1/[[:alpha:]]+|(_)/(?1: :\u$0)/g}}"}${RAILS_TEMPLATE_END_RUBY_EXPR} ${RAILS_TEMPLATE_START_RUBY_EXPR}f.text_field :${1:attribute}${RAILS_TEMPLATE_END_RUBY_EXPR} </div>
4 months ago
I used this:
Preventing caching in Rails controllers
giantrobots.thoughtbot.com/2008/4/25/pitfalls-in-restful-wizards
Much as our Exceptional competition is "healthy," Thoughtbot are a smart bunch. Paperclip is a top drawer attachments plugin and this post by Chad Pytel is an interesting read on how to prevent pages being cached in Rails controllers. Normally caching is a useful tool for improving the response of your webapps, but in many cases you want the data to be fresh on every request. Take home point: if you want your page to be 'cache-resistant' in Safari and IE, stick an empty iframe in it.
4 months ago
I photographed and posted this:
Photos from the Dublin Twestival
www.flickr.com/photos/paulmartincampbell/sets/72157613755154460/
The Dublin Twestival was on last night. Lots of people, lots of fun. Cool to see a LOT of faces that I've not met before alongside a healthy dose of regulars. Bonus appearance from and photos of Twink, who showed up with an entourage from BScene model agency. Crazy. Hope you enjoy my photos. I got a good one of Twink and another good one of Jason Byrne.
4 months ago
I helped to make this this:
Twecipe
Niall Harbison tweeted last Saturday that he had an idea for an app that he wanted done quickly. We got on board straight away. I hacked a prototype together, Eoghan did the design and Des helped with the all the projecty bits. Twecipe was born yesterday. I'm quite proud of how much we got done in just a few days, while keeping plenty of time for client work.
4 months ago
I needed this:
Fix for when Apple-Tab not working
My Apple-Tab key combo to switch apps wasn't working. Des gave me a neat little one liner to fix it:
killall Dock
This stops the Dock, which gets automatically restarted by OS X, and very quickly Apple-Tab works again. Sweet
4 months ago
I totally, totally, totally agree with this:
"The best part of building ‘as little as possible’ comes after launch. Every feature you skipped or held off on is free open space in the app for later development."
4 months ago
I plan to go to this:
Doctor Millar comeback shows
Doctor Millar is playing Dublin tonight in Bewley's Cafe Theatre. I recommend the show. He's also playing next Wednesday, which is when I plan to go see him.
4 months ago
I am very impressed with this:
Transparent background screen effects
http://www.flickr.com/photos/w00kie/sets/180637/
Setting desktop backgrounds to mimic what's actually behind them. Very smart. Very creative. I really like the transparent one
4 months ago
I wish more people would think like this:
The Little Coder's predicament
http://whytheluckystiff.net/articles/theLittleCodersPredicament.html
"You’ve got to be able to write a single line of code and see a result." _why nails it.
4 months ago
I empathised with this:
"What should have been a one-line code fix is turning into another QuickBooks spelunking expedition."
4 months ago
I photographed this:
Photos from the Innovate Europe drinks in 4 Dame lane
http://www.flickr.com/photos/paulmartincampbell/sets/72157613520432501/
I went along for drinks with all the lads who had attended the Innovate Europe event with EI last week. As usual, I had my camera so I snapped a bunch of headshots. I think there are a few high-profile guys in there.
4 months ago
I took this:
My housemate built a snowman over the weekend. He looks kind of sinister, but it was really cool to get enough snow to build a snowman.
4 months ago
I wrote this:
Stuffing CouchDB into Rails
Stuffing is a Rails plugin that lets you add a CouchDB data store to an existing ActiveRecord model.
class Post < ActiveRecord::Base
stuffing
end
The Post model above is just an ordinary ActiveRecord model. It has a MySQL table called "posts" behind it. The fields in the posts table get mapped to methods in instances of Post. But it also has the meta-attribute: stuffing. You can assign a hash of arbitrary keys and values to the stuffing method and it will be persisted automatically to CouchDB.
It works like this:
@post = Post.new({:title => "Cake", :post_type => "recipe",
:stuffing => {:ingredients => ['flour','sugar','eggs'],
:description => 'mix them all up'})
@post.save
@post.stuffing
=> {:ingredients => ['flour','sugar','eggs'],
:description => 'mix them all up'}
When you save this, with @post.save, the :stuffing gets saved to CouchDB. You can retrieve the attributes by accessing the stuffing hash: @post.stuffing['ingredients'] or you can call them by prefixing stuffing_ : @post.stuffing_ingredients. The data gets updated when you update it. It's just like having a big mega-hash in the sky on top of regular old ActiveRecord.
What's the point? Why not just use a CouchDB wrapper like ActiveCouch, CouchRest::Model etc.? Well, CouchDB has a lot of features. It's got javascript views with map-reduce, crash-only design, schema-less documents, bi-directional replication. Lots of really cool stuff that one day we'll all have in our own living rooms. But right now, today, it's only really the schema-less design that appeals to me. I mean, I love the other stuff, but when I'm quickly prototyping an app (as I often am in Rails), I love the idea of just being able to add another field to a form and bam! I have a new attribute. But then I want to be able to quickly hook on all the tried and true ActiveRecord plugins that I'm used to. Hell, I want to be able to call Post.first, Post.last and Post.all.
Stuffing helps to gently add a CouchDB layer to your Rails app without completely removing you from ActiveRecord. Think of it like swimming in CouchDB with arm-bands. Or like a Couch, but without the covers, trimmings or fancy coasters. Just the stuffing.
The plugin is yours, available to enjoy on Github: http://github.com/paulca/stuffing/ where there's a full documentation and some more examples. Feel free to contact me if you have any questions, or fork the project and patch back if you think I screwed something up, or if something can be improved.
4 months ago
I wrote this:
Playing with CouchDB over the last few months
I've had such a good amount of time with CouchDB over the last few months. I first read about CouchDB when I was back in college on Tobias Luetke's blog. It sounded awesome, but that was about that. At the time, it was quite complicated to get up and running, at least too complicated for me.
Then last year I met Jan Lehnardt and the game changed a little for me. I knew someone connected directly with the project. It became exciting for me. Jan got me up and running with a masterclass in CouchDB at RailsConf Europe last year. My appetite was squarely whetted.
My first foray into CouchDB was a little experiment called "Couchy". Couchy uses a TemplateMap class to parse fields out of HTML and create a schema out of them. It was a fun little project and got me up and running with the basic concepts.
It was a while before I got to try anything else, but in the meantime, Chris Anderson had published CouchRest::Model, which was very interesting, because it attempted to create more ActiveRecord-like models out of CouchDB, including dynamic views. It was full of smart stuff.
I got my hands dirty with CouchRest::Model building the first iteration of this little tumble log. I wanted a dynamic data store so that I could post any kind of content - a post, a quote, a link whatever, but I wanted to add to these easily in the future. Not like create a new database field or fill out some crazy schematic. Like just add a new form and I'd have a new post type.
I got quite far with CouchRest::Model, but then a cascade of issues hit me. What about pagination? What about attachments? What about search. All of these things have been solved really well with will_paginate, Paperclip, ThinkingSphinx. There had to be another way.
Today, in about 20 minutes, I was able to take the cool schema-lessness of this little tumble-log and hook it into a couple of ActiveRecord models that I'll be able to use with the above plugins and ActiveRecord finders. I used "Stuffing" a little plugin I wrote to do just that. Stuffing is the subject of my next post.
4 months ago
I stopped maintaining this:
My old blog
This is my old blog. I used Mephisto, which I quite liked, but I found that it ... wasn't just for me. So like any good hacker, I wrote my own blogging engine. And away I go.