Wednesday, September 27, 2006

Digg, Ruby, & Cocoa

I recently discovered that Digg allows you to simplify story submission for readers by placing a "digg this" link on your website. That sounded like a reasonable thing to do for my blog entries and after reading Guy Kawasaki's blog about it, I decided to give it a whirl. It wasn't long before I found myself wanting to automate the generation of the anchor tag. So I immediately ran off to my Ruby editor and generated a little script:

require "erb"
include ERB::Util

title, description, url, topic = ARGV[0], ARGV[1], ARGV[2], ARGV[3]
puts <<EOS

<a href="http://adigg.com/submit?phase=2

&url=#{url_encode(url)}

&title=#{url_encode(title)}

&bodytext=#{url_encode(description)}

&topic=#{url_encode(topic)}">

<img src="http://digg.com/img/badges/91x17-digg-button.gif"

width="91" height="17" alt="Digg!" border="0" />

</a>

EOS


That worked reasonably well, but then I started thinking back to all the stuff I learned about Mac OS X software development with Cocoa and decided that I should really wrap up my cute little Ruby script with a Cocoa GUI!

So I immediately opened XCode, generated a Cocoa application, and started messing around with Interface Builder. Here's what I came up with:



From Interface Builder I stubbed out my controller class (MVC after all!) and wired the button to an action method. I also decided to use Cocoa Bindings to wire the text fields to NSString properties in my model without any code. Now since my model only needed to expose four string properties (one for each field in my window) I chose to cheat a bit and just added the four properties to the controller.

Since Objective-C doesn't have automatic memory management, you typically manage the memory allocation and deallocation in the accessors. Fortunately Accessorizor came to my rescue and generated that code for me. So the only thing left for me to code was to pass my four text values to my Ruby script. A simple Google search resulted in this page on Cocoa Dev Central that describes how to call the 'ls' unix command from Cocoa. I quickly adapted it for calling my Ruby script. The one change I made was that I added my Ruby script to my XCode project as a resource so that it would be included in the application bundle at build time. So I added this line for finding it:

NSString *path = [[NSBundle mainBundle] pathForResource:@"digg" ofType:@"rb"];


Finally I decided it would be nice to just put the generated anchor tag on the clipboard when I click on the "Digg It" button. So I perused my "Cocoa Programming For Mac OS X" book and added these three lines:

NSPasteboard *pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
[pb setString:string forType:NSStringPboardType];


and voila:


Digg!

Sunday, September 24, 2006

Rethinking the car



Here are two extraordinary cars that I discovered through the magic of the internet. One is the Tesla Roadster. The Tesla is fascinating because it redefines what an electric car can be. How does 0 to 60mph in about 4 seconds and 135mpg equivalent all wrapped up in a gorgeous sports car package sound? Nikola Tesla would be proud.

Then you have the Ariel Atom. A stripped down minimal sports car with a phenomenal power to weight ratio but no windshield. You have to see this one to believe it. It's amazing.

I'll take one of each. ;-)

Wednesday, September 20, 2006

Ruby User Group Meeting

Last night I attended my first Ruby user group meeting. I've been a member of a lot of user groups and so my expectations were (perhaps unreasonably) high. My initial impressions weren't that great and I left the meeting unsure whether or not I'd return the following month.

But then I started to think about it:
  1. Here were a bunch of geeks (me included) getting together to talk about a nascent technology in a city largely dominated by Java and .NET. The fact that these people cared enough about fostering the growth of the language and framework to set all this up is commendable.
  2. The presentation was actually quite good. I came out of there knowing something about Capistrano that I didn't know before I went in there. It inspired me enough to go looking at the Capistrano and Mongrel websites.
  3. The group was roughly 20-25 people. Not bad when you consider very few of us are actually getting paid for writing Ruby.
  4. There were door prizes (a couple books from O'Reilly and no, I didn't win). The people in charge are trying to entice people to come and learn and share.
So I reconsidered. I'll probably continue to attend and hope to see the technology and user group flourish. Only with growth (and perhaps some corporate sponsorship) can we eliminate poor first impressions like the one I had. In the interim, I'll continue to learn, make contacts, and maybe if I learn enough I'll be able to give a presentation one day too.

Thursday, September 14, 2006

Set phasers to stun...

The last couple days have been a bit painful for me as I've endured exposure to the white hot burning effects of crappy UI design. My crap-block was only at an SPF level of 20 and I really should have just got the all-over environmental suit and properly protected myself.

Seriously, I don't understand why so many people undervalue good user interface design. At the very least, people should expect some consistency. Love 'em or hate 'em Apple set some pretty good keyboard conventions with:

Command-S == Save
Command-A == Select All
Command-X == Cut
Command-C == Copy
etc.

Even Microsoft's Windows 95 decided to copy Apple's Command key combinations with the likes of CTRL-S and CTRL-A (they even figured out CTRL-X, CTRL-C, CTRL-V for Cut, Copy, & Paste instead of that abomination that was Shift-Del, Ctrl-Ins, Shift-Ins in Windows 3.1).

Apple's human interface design was also heavily copied. For example, potentially destructive user actions were met with a nice little dialog box asking the user to confirm their action.

So imagine my surprise and frustration today when I pressed Ctrl-S to save my work and this ridiculous application promptly threw away my data and selected (as in SQL select) the data from the database again! What I don't understand is that a committee of people reviewed a number of these vertical market candidate applications and chose this one as the best. Good lord I can only imagine what the others looked like!

Thursday, September 07, 2006

JRuby on Rails


It was only a week ago I was waxing philosophically about Enterprise Software and mentioned that Ruby was in the early stages of running on the JVM and .NET CLR and just today Sun announced that they're hiring the JRuby developers to continue their work full time at Sun. Wow! That's big news. Maybe mainstream Ruby on Rails development won't be far behind... Ahh the winds of change.

P.S. I tried JRuby a few weeks ago after Rails went to 1.1.6. The Gem system actually worked to fetch rails and I was able to create a skeleton rails app and start webbrick. It didn't work much more than that (which was still very impressive) and it was definitely slow but that proof of concept gives my high hopes for this project.

Tuesday, September 05, 2006

User Interface Development

Given the same amount of time, who is more productive... a small team of multi-talented developers? or a large team of specialists? Since I think the answer lies with the multi-talented crew, I took stock of my own skills and decided it was time again to strengthen my ability to create web user interfaces.

So here was my plan: design a web page or two in a graphics tool of some sort and then translate it to an xhtml/css implementation that I can then make dynamic at some later date with something like rails.

I started by perusing the css zen garden for inspiration. Then while keeping the goal of simplicity and efficiency in the back of my mind, I opened OmniGraffle and threw together some nice curves, a healthy amount of translucency, a decent colour palette and quickly had a design.

I then moved onto creating the browser implementation. It was simple enough to create the bare-bones xhtml to represent he text of my fictitious website. But then I ran into my biggest skill deficit, a weak understanding of css. I've read books and coded a lot of this stuff in the past, I just didn't have the big picture. I couldn't make the html tags do what I wanted. I even got so desperate that I almost resorted to the the evil "table" tag. Fortunately I stumbled across Mike Hall's BrainJar website.

He has some great descriptions (with diagrams!) of css positioning, the box model, selectors, etc. After absorbing some of that good information I was soon off and running again.

But no sooner had I started coding than I found myself in the nasty world of css standard unconformity. You see I wanted to take advantage of some of the css3 enhancements I was reading about and unfortunately they weren't working.

In the past I've always relied on Firefox to be the standards compliant browser, but I discovered that the nightly build of Safari/webkit has support for just the properties I needed (i.e., border-radius and multiple background-image properties). For the Firefox fans you probably know that it also supports -moz-border-radius, but Safari's anti-aliased rendering without artifacts is definitely superior.

So a couple "float:right;" properties here, a "-webkit-border-radius:15px;" there and I pretty much got what I wanted. I did discover however that content and style are not as cleanly separated as a I thought they would be. I still ended up nesting a couple div tags and placing content in a certain order so that the float property would do what I wanted but regardless I'm pretty happy with the end result. Next will be dealing with the various browser differences. And I bet Windows IE will be the big pain... PNG support sucks, CSS support is spotty, I'll let you know...