Saturday, March 25, 2006

Tired: Amazon Lists; Wired: All Consuming and Lists of Bests

I've been under a large rock for the last month, so it came as a surprise to me that the Robots had done it again and expanded their suite of free online apps for managing your lists.

In addition to 43 Things, 43 Places, and 43 People, they have integrated All Consuming with a new offering - Lists of Bests.

I've always been dissatisfied with Amazon's list and recommendation implementations, primarily because they've lacked the ability to create lasting personal networks along with threaded discussions and recommendations among folks with similar interests. In my mind Amazon has created more of a competitive and individualistic network on their site (Listmania!, My Wish Lists, Top Reviewers), rather than a truly cooperative community that openly shares information and builds trust over time.

Amazon's new "Customer Discussions" beta seems to be an attempt to finally address this deficiency, but the very name they chose for this feature belies how they view you first and foremost - as a customer, not a member of a community.

I think the Robots' approach is more savvy because it's more about people's interests and interactions than just the things they buy. The community tools they are building with their integrated sites recognize that we humans are multi-faceted* social creatures - we do things, we have opinions, we consume, we meetup, and we go places - together! And of course, their designs are simply KICK-ASS!

* subliminal nod to Ruby which the Robots use to build their stuff. ;)

p.s. The Robots provide a simple javascript API to display your All Consuming list on your blog or web page. I've added mine here, below and to the left.

Monday, March 13, 2006

Road Trip! Rails week in April.

It's a done deal. I'll be heading to Portland for the Rails Pragmatic Studio and zipping up to Vancouver immediately after for the Canada on Rails conference.

I'll probably drive so if anyone needs a ride down from Seattle or up from Portland to Seattle or B.C., drop me a line.

I'll be taking the TDI so I think a full tank of biodiesel may get me there and back again.

Does anyone know of any biodiesel stations en route just in case?

Sunday, March 12, 2006

Dating Ruby. And Mom, I think it's serious this time

I finally got around to downloading the December meeting of the Chicago Snakes and Rubies. DHH gave a presentation where he talked about his "pursuit of beauty" within Ruby and the Rails framework, and starts his talk with a quote from the physicist Richard Feynman which is worth repeating:

"You can recognize truth by its beauty and simplicity.
When you get it right, it is obvious that it is right."

-- Richard Feynman, Scientist


It got me to thinking about BEAUTY, along with my somewhat jaded dating history with certain programming languages which should go unnamed. OK, why not kiss and tell: Basic (H.S.), Pascal (University), C++ and Perl (Adobe), Java, Visual Basic and C# (IDX/GE) - in that order. I can't but help wondering now if I'd only gotten to know Ruby better earlier, how much heartbreak and mental anguish could I have avoided?

But I guess you can't expect your first love to be the one true love of your life, like in the fairy tales. You've got to put yourself out there, mingle a bit, kiss a few frogs, test the waters, have some blowout fights, win some and lose some to know what's possible. After all, how many seasons did it take for David Addison and Maddie Hayes to finally hook up? Love is HARD.

I suppose there is some truth to the old saw that what doesn't kill us makes us stronger. But I can't help wishing I could at least get back some of the last 11 years and spend a bit of it with that mysterious beauty from the Pacific Rim, Ruby. We had a brief flirtation in the late 90's. Nothing serious. Passing ships in the night really. We met at a speed dating event. We had scheduling conflicts and then we lost each other's cell number. Bad timing, I guess.

At the time I was distracted and fairly into Perl. She wasn't my first, but she taught me a lot. While there were things I really dug about her (regular expression handling, reporting, file operations), she just never fit well with my mental makeup. Not very objective and way too religious: all that "bless"-ed sillyness. (To Ruby, everyone is a child of God.)

I don't want to seem shallow here, but I'm sorry, forget beauty even with a small "b." She was far from a looker. I think was primarily attracted to her nimble efficiency and subtle - dare I say Vulcan - intellect. But half the time I had to get her to repeat herself six ways to Sunday to finally get what she was trying to tell me. No universal translator for us, no "my mind to your mind, my thoughts to your thoughts." And sooo indecisive. Trust me, the last creature in this or any other galaxy you want to date is a wishy-washy Vulcan.

So, when I later met Python, that alluring snake in the grass, in a local dive bar, I found and immediate appeal in her strict constraints and draconian philosophies. Unlike Perl, Py was a no-nonsense dominatrix who laid down the law, smooth black leather whip in one hand, ostrich feather in the other. And man, did you like it. You couldn't get enough. When it hurt, it hurt GOOD. And she always left you wanting more, more, MORE!

But then, I abruptly ended it. She struck me as a tad bossy and, frankly, a bit castrating. Always insisting I do things her way, crossing all my t's, etc. I admit that maybe my male ego got in the way. And perhaps it was also a style thing. No one's fault. But I had needed a bit more freedom. Nevertheless, we still talk. In the end, I think we might make good platonic friends, the kind you call up at the end of a rough day for a little perspective.

But after my brief affair with Py things went seriously down hill for me. You see, over the past five years I've been seeing a lot of Java and C#. I met both of them at work after a painful re-org, which makes me think I was probably on the rebound. Licking my wounds, I suppose I wanted more stability, a sure thing. As if.

I found them both compelling for many reasons. Like a lot of my friends and coworkers, I got sucked in by their sexy promises. And what a HUGE network of friends and family. And I confess I'd never been asked to participate in a threesome. So what red-blooded guy is gonna say no to that? (Though it did bug me how afterwards they were always comparing each other's performance in bed, ad nauseum).

But when you get right down to it there never has been much physical attraction there. Very little chemistry between us. Just going through the motions, really. Nothing like the blood-rushing zing I had with Py, or even the "ahas" from my long conversations with Perl. Anyway, it's probably a bad idea to date two of your coworkers. Better to meet at an out-of-town bar or in an AOL chatroom.

OK, here's the truth. They're really not that hot after you spend much time with them. I'm just not that into them. They just aren't that beautiful to me.

Case in point...

What better way to "compare" them to Ruby than with Java's Comparator/Comparable, C#'s IComparable, and Ruby's sort_by for Enumerable implementations for sorting. (How "meta" is that?).

I won't clutter up this already long post with the Java and C# ugliness (there are fine examples in the previous links), but here is Ruby's terse, elegant, and BEAUTIFUL solution:

class Person       
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
end

people = [ Person.new("Andy", "Hunt"),
Person.new("David Heinemeier", "Hansson"),
Person.new("Dave", "Thomas"),
Person.new("Yukihiro", "Matsumoto") ]

sorted = people.sort_by {|person| [person.last_name,
person.first_name] }
sorted.each { |person| puts "#{person.first_name} #{person.last_name}" }

==>

David Heinemeier Hansson
Andy Hunt
Yukihiro Matsumoto
Dave Thomas

I think it's not surprising who I'd rather take home with me from this party. Assuming I haven't had too much to drink.

This is of course, just one example, but I think it is representive of the differences in their expressiveness. And it illustrates the BEAUTY of some of Ruby's concepts like blocks and closures that are available to other dynamic ladies like Lisp, Python, and Smalltalk.

Now I find my heart pining for what I've been missing, the dynamic nature of some of my earlier loves.

So last year, I took a leap. Tracked down Ruby again (thanks Google!). Apparently she was still available, hadn't settled down one bit (no 2.3 kids, Chrysler mini-van, and surburban cell for her). She has an even bigger network of friends (and lovers), is doing some really amazing things with this Danish guy, and is as open to the world as ever.

Here's my thinking. I figure that I dump Java and C# for a fulltime relationship with Ruby ("Sorry, girls. But it's you - not me - this time."). I increase my happiness by an order of magnitude of 10 (at least!) and I'll be 10 billion times more productive. I should make up for those lost 11 years in no time flat.

Of course, this will mean some major changes in my life. A lot of work and risk. But maybe that's the price of true love. It'll be worth it all if, at the end of each night, on the long walk home from the date, I can look up into the night sky and get that same oceanic feeling I had so many years ago. That life is good, beauty is all around me, and I can once again kiss the stars.

Saturday, March 11, 2006

Barbarians at the Gate?

I think Gosling is in total denial about Java losing ground with a large class of problems and developers. Some of the top Java evangelists are turning to Ruby because they feel ignored and to some extent betrayed.

His comment about Ruby being just a scripting language that generates
web pages without power in the application domain shows a lack of
understanding of Ruby as a provider for DSLs. If he'd ever actually looked at any Rails code surely he would see this. ERB, embedded ruby, is what actually generates web pages (from rhtml templates) in Rails. Rails itself is a DSL with ORM, cross-cutting concerns, and business logic written in Ruby. Ruby's power to create DSLs shows that Ruby is the anti-thesis of a specialized language (as Gosling claims) and it's one of the reasons DHH wrote Rails in Ruby.

PHP's main problems are much like Perl's: bolted on OO lacking DSL
capability. And it's grown too organically to be consistent and
manageable. Ruby has the advantage that the language has borrowed
concepts from the best of Smalltalk, Python, Lisp, etc. and the
community has been small and smart. It's found a pleasant balance
between Python's rigidity and Perl's TMTOWTDI ("There's More Than One Way To Do It").

And Gosling's comment about complexity reveals that he may not subscribe to Einstein's maxim: "Make everything as simple as possible, but not simpler." Perhaps Gosling's version would be "Make everything as difficult as possible, even the simple things."

Instead of fiddling while the city burns, Java would be better served by leaders who took these realities to heart and talked about how they are going to address them.

I can understand why they want to protect their language's persona, but if they really want to keep their customer base, I think they should "get real" and take some advice from the guys at 37signals about being forthright and responsive: admitting your faults to customers and fixing them as soon as possible.

Take it from someone who spent almost 3 years in technical support and training, this is how you build lasting customer loyalty. Through acceptance that you are not perfect, the desire to improve, and an honest willingness to help your client. Not through denial and neglect.

Wednesday, March 08, 2006

Established corporate healthcare IT, meet your new competition

I'd like to introduce you to a Revolution.

First you should check out who is on the board of directors, then take a peek at the executive team leading the charge.

Now take a look at the technology they'll be using. The 3 R's are for Ruby on Rails for the Revolution.

Did the earth just move a little?

Are you worried?

You should be.

Friday, March 03, 2006

Subversion ASP.NET hack - Ruby and Rake to the rescue

I recently began using Subversion to manage some Microsoft VS.NET solutions when I encountered this nasty problem with ASP.NET web projects. No one seems to know exactly why, but VS.NET has trouble loading Web projects from the server when there are folders that begin with a dot.

Tigris does offer a hack workaround that simply renames the ".svn" folders to "_svn", but it requires that you constantly change environment variables and reboot your system if you want to keep your .svn directories and remain compatible with command-line svn and other non-Windows systems.

After listening to Geoffrey Grosenbach's Ruby on Rails podcast with Jim Weirich about his most excellent build tool Rake, I thought this would be a case for the dynamic duo.

So I picked up the Batphone (you did notice it is red, no?), and a few minutes later I had a way to switch the directories to an ASP.NET compatible version any time I need to reload the Web project. It takes under a second to recurse over 2,000 folders on my Dell D600. Not bad, especially considering how long it takes that cursed laptop to reboot.

Ruby Fu! HIYAH!!

fileutils.rb:

require "ftools"

module YaYaSoft
class FileUtils
def self.rename_all(dir, from, to)
return nil unless FileTest.directory?(dir)
Dir.foreach(dir) do |e|
next if [".", ".."].include? e
fullname = dir + File::Separator + e
if FileTest.directory?(fullname) && e == from
puts "Renaming #{fullname} to #{to}"
File.move(fullname, dir + File::Separator + to)
elsif FileTest.directory?(fullname)
#puts "Checking directory: #{fullname}"
rename_all(fullname, from, to)
end
end
end
end
end


rakefile.rb:

require 'yayasoft/fileutils'

DIRS = ['../webapps/Web', '../webapps/dotNET/WebService']

desc 'Switch to ASP.NET compatible'
task :switch_aspnet do
DIRS.each do |dir|
YaYaSoft::FileUtils.rename_all(dir, '.svn', '_svn')
end
end

desc 'Switch to standard .svn'
task :switch_svn do
DIRS.each do |dir|
YaYaSoft::FileUtils.rename_all(dir, '_svn', '.svn')
end
end