jlaine.net

Apress Blogging Contest @ on Ruby

Rails Revelations: How Rails made me a better programmer

For me, the spell of Rails comes roughly in three parts:

  1. Productivity boost
  2. Having more fun
  3. Doing the right things

Number 1 has been the reason numero uno almost everywhere Rails has been mentioned. I guess it’s easier to sell productivity to managers than having fun (“oh, that’s so unprofessional!”) or doing the right things without rigid explicit processes. However, I see the increased productivity mostly as an inevitable consequence of the two latter points.

Much of my liking Ruby and Rails development more than other environments comes from the feeling of the language and tools being a natural extension of my brain. Why shouldn’t I be able to write something like 2.weeks.ago? It’s easy to dismiss things like that as just syntactic sugar without real meaning, but you know, things add up, and overall happiness in work is built of small details.

Point number three could be described as the dullest and most minor benefit Rails brings to table. However, in many ways it’s the grounding factor of both the happy Rails development and the improved productivity.

The things I include in doing the right things are stuff like making testing as easy as not to, conforming to the Rest principles and naming conventions, the MVC-type separation of concerns, and keeping yourself DRY. I sleep my nights much better when I know that my application has extensive test coverage and that anyone knowledgeable with Rails can take it up in a few hours in case we need more labour force because the structure of the application is so obvious.

Now, none of these things are specific to or even popularized by Rails. However, many web developers have come to learn these lessons through Rails and I don’t know any other framework that would make them as integrated part of the development process as Rails does. As the king of the Rails kingdom, David Heinemeier Hansson, has said, Rails tries to be the angel on the developer’s shoulder (“Write your tests, it’s as easy as not to!”) as opposed to the PHP devil (“SQL in the views, quick’n’dirty, man!”).

However, my imagination is very limited and I’d like to hear more about what healthy habits Rails has made people learn and what bad habits to abandon. That’s why the topic of our January blogging contest is “Rails Revelations: How Rails made me a better programmer”. Heck, if Rails made you quit smoking, tell us about it.

Welcome Cairo

I just upgraded my browser of choice to the latest nightly build. Camino 1.0.3 has been anything but stable recently so I wondered the latest bugfixes can hardly make it worse. I got the spark from Mr. Hicks who had a comparison between how the new Cairo rendering engine, Safari and the old Camino render light text on a dark background.

Of course, it will come with some other new goodies, too, like (finally) a RSS feed icon in the address bar, nice rounded corners and automatic spell checking in forms.

So far the build of December 19 has been rock-solid (for a whopping hour ;-), so no complaints. And the new text rendering is nice.

Microsoft Provides Free IE6 Virtual Machine for Web Developers

When developing dotherightthing.com, it’s been a real PITA to develop for Internet Explorer. I’m working on a Mac and have to do the Windows testing on the _gf_’s laptop. After I installed IE7 on the box, there was no easy way to run version 6 on it anymore. However, IE6 and IE7 both have their quirks which are, of course, completely different from one another. As sad as it might be, IE6 is still the most popular browser on the market, so the situation was untenable.

I tried to use a standalone IE6 from the Browser Archive, but unfortunately I couldn’t even login to our dev system using it. It seems that it really isn’t that standalone and gets the cookies somehow mixed up (or doesn’t accept them at all, dunno), so the value of it was practically zero.

Luckily, for once something really useful from the MS land: IE6 and IE7 Running on a Single Machine: free Virtual PC 2004 + a virtual machine for testing on IE6. Haven’t yet tested it but it sounds cool enough for small teams that don’t want to spend on Parallels + a Windows license or another Windows machine just for debugging the IE6 hell.

(via Assemblix)

Companion Site for the Book

I set up a companion site for the book at railsecommerce.com. If you can’t access it yet (it’s still traveling around the DNS servers of the world), it can also be found at jlaine.net:8010.

The site already has the sample code for the book, and will also sport the errata and a few sample chapters as soon as I get the system up and running. We will also be writing articles about all things related to Rails and E-Commerce on the site.

Check the site out and don’t forget to subscribe to the Atom feed!

Beginning Ruby on Rails E-Commerce Is Shipping!

Dear Rails Enthusiast,

We just got email from our editor Keir where he said he’d got his
hands on our new book, Beginning Rails E-Commerce. His mail didn’t
include the words “f*cking awesome”, but instead “superb” and
“a work of art”, which we think are almost as good.

This means that the book will hit the shelves before you can say
“Heinemeier”, so be sure to get yours while it’s still hot.

We wanted to make our book such that you can “read” it while you’re
sitting in front of your computer. It’s completely project-driven,
meaning the content is divided by task, and that you can build
the sample application in small iterations, learning the
background details on the fly.

As one of the core philosophies of Rails is to support best
practices, we decided to do that as well. Most of the tasks are
written test-driven, giving you a glimpse of the ease with which
TDD can be used in Rails and the power it brings compared to a
traditional, ad-hoc web application development process.

We hope you enjoy the book as much as we enjoyed the journey of
writing it.

Buy the book

Best,

Christian Hellsten and Jarkko Laine

Spam Statistics

Filtered Mail

84040 Good Messages

19581 Spam Messages (19%)

19 Spam Messages Per Day

SpamSieve Accuracy

91 False Positives

162 False Negatives (64%)

99.8% Correct

Corpus

2286 Good Messages

2485 Spam Messages (52%)

167105 Total Words

Rules

1460 Blocklist Rules

2529 Whitelist Rules

Showing Statistics Since

30.1.2004 18.11.26

SpamSieve rocks. I just wish it would have some kind of connection to the server so that the screening could do already on that level. That way the spam butchering wouldn’t depend on me reading my mail through Mail.app.

My Rails Presentation at Openmind 2006

I’m here today to talk about Ruby on Rails. I’m sure many of you have heard about Rails before, but for those who haven’t, Rails is a full-stack Model-View-Controller web application framework suitable for rapid application development, meaning it includes everything from an object-relational mapping layer called ActiveRecord to ActionController to ActionView.

I’m not going to give you a full introduction to Rails, since the time doesn’t permit that. Instead, I’m going to frame this talk by telling why Rails is reaching its tipping point.

The Tipping Point is a best seller book by Malcolm Gladwell. It gives an interesting explanation of why change so often happens as quickly and as unexpectedly as it does. Not following a straight line but a hockey stick curve like this example depicting the success rate of podcasting shows. The point where a steady and slow trend abruptly skyrockets (or plummets) is called the tipping point.

For example, why did crime drop so dramatically in New York City in the mid-1990’s? And why word-of-mouth is so powerful? If you haven’t read the book, I strongly recommend it. You know, Santa Claus is coming and everything…

Gladwell presents three things that must be in order for any phenomenon to reach its tipping point:

  1. The law of the few
  2. Context
  3. Stickiness

If any of these three (which we’ll go into in detail in a minute) is lacking, it’s hard or impossible to reach the tipping point.

Presenting Rails in this context is by no means an original idea, actually I got the idea from a blog post by David Geary, who is – a bit ironically – a Java guru (author of Graphic Java and Core JSF) turned into a Rails addict.

The Law of the Few

In the end, every success story is about people. And not just any people but the right kind of people.

According to Gladwell, to be successful, any phenomenon needs three kinds of people: salesmen, connectors and mavens.

Salesmen

Salesmen are the kind of people that can sell you a whole kitchen when you were just going to buy a new coffeemaker.

The creator of Rails, David Heinemeier Hansson, is a natural-born salesman. Not only does he look like a Gant model, he’s a mesmerizing talker, always being genuinely excited about all the stuff he’s talking about. He’s also not afraid to poke the beehive to create the needed buzz. Some people think he’s arrogant, but he’s just very true to himself doing his own, great, admittedly opinionated stuff. And… as Don Norman puts it: “If someone doesn’t really hate your product, it’s mediocre.” You don’t wanna be mediocre if you want to tip.

But it’s not enough to have a salesman like DHH to spread the word. There are two other kinds of needed people, too. In the case of Rails, the two are often combined in the same people but the needed characteristics are quite a bit different.

Mavens

Mavens are people that love to acquire knowledge about different topics and to share that information with others. They’re the people that have more than a thousand subscriptions in their feed readers. For Rails, quite a bunch of high profile mavens got excited about Rails early on and let the world know about it. Tim O’Reilly probably doesn’t need an introduction, and neither does Dave Thomas. James Duncan Davidson, the creator of Ant and formerly part of the Java team at Sun, is now a hard core Rails guy. Mike Clark, Jason Hunter, Bruce Tate, Dion Almaer, Stuart Holloway, Justin Gehtland, Glenn Vanderburg, and the aforementioned David Geary are all some of the biggest Rails evangelists now. You wouldn’t think that seeing the books they’ve written previously.

Connectors

The last group of people crucial for the success of a product is connectors. They are the hubs of word-of-mouth epidemics, the people that know “everybody”. I myself have 47 connections in LinkedIn, which I think is ok, the average for people I know is more like 20. The conference chair at O’Reilly, Nat Torkington, has 325 connections. He’s the kind of connector that is crucial for spreading the Rails virus.

Context

Whether there are the right people advocating the cause, a product like Rails just can’t tip if the context is wrong. The context strongly affects how people react to different stimuli. The Tipping Point describes a study where researchers at the Princeton University told seminary students to prepare a short talk about a given topic and go present it in a nearby building. Between the two buildings there was a man who was obviously in agony and in the need of help. The purpose of the study was to see who would stop and help.

Some people were given the good samaritan as the topic, others got some random topics.

After the talk was ready, the instructor said to some students that they’re already late and that they should hurry up. To others, they said that they still have some time but that they can as well head over now.

It turned out only 10 percent of those who were said being in a hurry stopped and helped the guy, as opposed to 63 percent of the students who had plenty of time. It didn’t make any difference whatsoever what the topic of the speech or the background of the student was. Indeed, many students rushing to give a talk about the good samaritan actually stepped over the fellow in agony.

That’s the power of context.

For Rails, the context we’re currently in is very favourable. As David Geary puts it, “Java was once developed as a simple alternative to overly-complex C++. But that was ten years ago. Now enterprise Java has grown into a behemoth that consists of layer upon layer of complexity.” This is a comparison of the amount of books needed to grasp the same amount of stuff you need with Rails in Java. As Jason Hunter puts it, “Java has opened the door for simpler alternatives.” And of these, Rails is certainly one of the strongest contenders.

If we approach the thing from another direction, PHP, the situation is also getting ripe for change. PHP is cool for simple hacks but a really bad match for anything that needs to be better structured and maintained. Flat namespace, anyone? However, the rigid Java frameworks just don’t cut it for the most of the disgruntled PHP hackers, so Rails is in a really good position even in this context.

Stickiness

And now for the part that talks about the Rails itself.

Good, so Rails has some marvelous people advocating it, and the time seems to be right for it. But it’s all for naught if the message doesn’t stick with the listener. It’s not enough to have the perfect salesmen and context for a product to really tip. People have tried that: to use a huge amount of marketing effort to sell something which doesn’t really have any content. It’s called a bubble.

So what’s making Rails stick? I think the most important thing in life… errr… stickyness, is love. Love, passion and happiness are what really drive people forward. And they are what Ruby and Rails are optimized for. Not sucking each and every cycle of the cpu to make the code run faster, but making the programmer happy, passionate, and thus more productive. Don’t know about you but I would be happy to shell out a few bucks for a faster server if that would make my programmers happier and more productive.

Currently, there are many people that are working on some “enterprisy” platform in their day job and then learning Rails by night. A month later they’re starting their own moonlighting companies, earning money by doing the stuff they love and are passionate about. If I would be a CTO at their day job, I would pay really close attention to this trend.

Most people hesitant about Rails are that only until they really use it. After that, most of them are hooked. Not everybody, Rails is opinionated and not for everyone, but more important than the amount of hooked people is the level of passion they feel about Rails.

So what is it in Rails that makes it stick with the hackers?

One thing that appeals to many hackers is the beauty of the Rails code (which is mostly thanks to Ruby). Actually the reason for DHH to write Rails on Ruby was because he “was unable to write beautiful code in PHP” :

User.find_by_name(“jarkko”).posts

class User
has_many :posts
validates_presence_of :email
end

That’s all very clean and should be understandable even for people never heard about Ruby or Rails.

Another, related principle in Rails is convention over configuration:

class User
set_table_name “users”
primary_key “id”

has_many :posts, :class_name => “Post”
belongs_to :group, :class_name => “Group”, :foreign_key => “group_id”
end

This is all fine and good. You can specify everything in detail just like you did before with framework X (except that you don’t need to do the XML situps). But imagine for a while it could be even easier. Imagine, what if it could look like this:

class User
has_many :posts
belongs_to :group
end

With Rails, it does, as long as we adhere to the common Rails conventions (which would be sane for a greenfield application anyway). Why make everything equally hard and ugly, when we can make the thing much more fun for the most of the users, for the most of the time? But like you could see from the previous slide, you don’t have to follow all the standards, you’re just strongly encouraged to do so.

Killer AJAX support

Rails core team is the home of the creators of two of the most prominent AJAX frameworks: Prototype and script.aculo.us. It has built in support and helpers to create Ajax calls and responses as easy as not to, without necessarily writing a line of actual Javascript.

The Ruby itself

  • Dynamic Typing
  • Reads out beautifully
  • Introspection
  • Open classes
  • Execute code in class definitions

In a word, Ruby just rocks. It’s the bread and butter. If you haven’t try it out.

It’s all that stuff (and a lot more) that makes Rails so great, and sticky. But don’t just take my word for it. Go ahead and test it yourself. There’s prebuilt packages for both OS X and Windows you can just install with one click and start using it. The web is full of tutorials on getting started. There’s also a couple of books published about Ruby and Rails. You can find them easily from amazon.com. One of them is especially close to my heart (because I wrote it): a shameless plug for our book that just went into print.

Resetting ActiveRecord Object Columns in Migrations

Often when you use migrations to keep track of your database schema, you also need to migrate data around in the database. You can use the execute method to do this in pure SQL, but since migrations are Ruby code and have access to all the ActiveRecord code, why not do it in there? Here’s an example from our latest project where I reverse a has_one—belongs_to association:

def self.up
add_column :images, :content_id, :integer

Content.find(:all, :conditions => “image_id is not null”).each do |entry|
image = Image.find_by_id(entry.image_id) rescue nil
if image
image.content_id = entry.id
image.save
end
end

remove_column :contents, :image_id
end

However, this has one problem. The Image class is loaded and the column information cached before the column content_id is added, so it doesn’t have the getter and setter methods for that column and thus image.content_id = entry.id will bomb.

Fortunately this is easy enough to fix. Just call Classname.reset_column_information after the column is added, and the new column will be found:

def self.up
add_column :images, :content_id, :integer

Image.reset_column_information
Content.find(:all, :conditions => “image_id is not null”).each do |entry|
image = Image.find_by_id(entry.image_id) rescue nil
if image
image.content_id = entry.id
image.save
end
end

remove_column :contents, :image_id
end

Installing Ruby MySQL Driver on OS X

Just noticed that I hadn’t installed the native Ruby mysql driver after getting the laptop back from repair. The reason it took a few days is that Rails just happily churns away with it’s built-in pure-ruby driver. However, the native binary driver is considerably faster and more stable, so you should never go into production without it. It won’t hurt having it installed on all your dev boxes, too.

However, installing the native driver on OS X wasn’t as easy as one would assume. If you have the MySQL binary OS X version from MySQL.com, it’s installed under /usr/local/mysql, and the gem can’t find it there. You can fix this by hinting the gem install command about the location of MySQL:

sudo gem install mysql — —with-mysql-dir=/usr/local/mysql

Unfortunately, this resulted in errors:

Probutanol:~ jarkko$ sudo gem install mysql — —with-mysql-dir=/usr/local/mysql/
Attempting local installation of ‘mysql’
Local gem file not found: mysql*.gem
Attempting remote installation of ‘mysql’
Select which gem to install for your platform (i686-darwin8.6.1)
1. mysql 2.7.1 (mswin32)
2. mysql 2.7 (ruby)
3. mysql 2.6 (ruby)
4. mysql 2.5.1 (ruby)
5. Cancel installation
> 2
Building native extensions. This could take a while…
mysql.c: In function âInit_mysqlâ:
mysql.c:2015: error: âulongâ undeclared (first use in this function)
mysql.c:2015: error: (Each undeclared identifier is reported only once
mysql.c:2015: error: for each function it appears in.)
mysql.c:2015: error: parse error before numeric constant
mysql.c:2018: error: parse error before numeric constant

Googling around helped, and Bob Silva came to the rescue: you can fix the errors by adding the following line to the mysql.c file of the mysql gem (/opt/local/lib/ruby/gems/1.8/gems/mysql-2.7/mysql.c for me):

#define ulong unsigned long

However, just adding it and re-running the gem install command doesn’t work. It turns out the mysql.c file is recreated by the extconf.rb configuration, so you need to do a bit of handiwork:

cd /opt/local/lib/ruby/gems/1.8/gems/mysql-2.7
sudo ruby extconf.rb install mysql — —with-mysql-dir=/usr/local/mysql/

Now add the line above to the created mysql.c file, and after that compile and install the driver by hand:

sudo make
sudo make install

That’s it, the driver should be installed. You can check it by running the gem list command:

$ gem list

* LOCAL GEMS *



mysql (2.7)
MySQL/Ruby provides the same functions for Ruby programs that the
MySQL C API provides for C programs.

Note that you might have the native driver installed even if you don’t have the gem (e.g. via darwinports). You can check whether the library is installed in irb:

$ irb
irb(main):001:0> require ‘mysql’
=> true

If it’s not installed, you will get something like this:

$ irb
irb(main):001:0> require ‘rubygems’
=> true
irb(main):002:0> require ‘mysql’
LoadError: no such file to load — mysql
from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:21:in `require__’
from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:21:in `require’
from (irb):2

Installing Subversion 1.4 on OS X

UPDATE, 1.11.2006 I updated the script to build neon (and thus subversion) with SSL support.

I just got my MacBook Pro back from a repair where its faulty hard drive was replaced. All the data was migrated but the system folder was for some reason rebuilt so I lost the installed Developer Tools, and along with that, subversion.

I installed the latest Developer Tools from developer.apple.com, but for some reason they don’t include subversion anymore. My next attempt was to install subversion from darwinports, but that didn’t succeed either. It seems that the ports version of subversion depends on apr-1.2.2, but all the mirror sites only have apr versions 1.2.6 and 1.2.7. I probably could’ve hacked it to use one of them, but then I figured the ports version would be kind of old anyway, since subversion was just updated to version 1.4. Thus, I decided to build it from scratch.

The problem with installing subversion from scratch is that it depends on a few other packages (included in the subversion-deps package) that need to be built as well, separately. So I hacked together a shell script that downloads the current subversion and subversion-deps packages and compiles and installs them:

subversion-1.4-install-all.sh
Usage:

sudo sh subversion-1.4-install-all.sh

(use sudo here to avoid writing your password multiple times during the course of the script)

Disclaimer The script worked fine on both my MBP and a G4 PowerBook. It should probably work fine on any *nix, but use at your own risk. If it doesn’t work, I will only return the price of the script.