I recently made the decision to start looking into Ruby on Rails 3. Partly this decision was fuelled by what seemed like a growing interest in the framework in the various forums I read; rails appears to be becoming the language of choice for open source web developers. I’d largely never really strayed too far from the Microsoft pond when it came to the web, with the exception of one or two php based pet projects, so not only would rails be new to me, but ruby too.
Microsoft’s MVC framework (which many including myself believe to be the final nail in the webforms coffin) seems to borrow quite heavily from the ideas introduced by rails. Now, neither Microsoft nor the Rails team “invented” the MVC pattern, but when applied to RESTful design and web development you can’t deny the similarities between the two. Given that rails pre-dates MS MVC by around four years, it became apparent that the open source community is the place to look if you want to see what Microsoft is going to do next.
Not only that, but the Rails community are as obsessive about standards as I am. Microsoft, particularly with webforms, seem to be trying their level best to create an environment where you can just completely ignore neat architecture, whereas with Rails it’s actually quite difficult to do things “the bad way”. All of this was enough to prompt me to check out the framework.
But I certainly didn’t expect to see this! Ruby on Rails, to a Microsoft aficionado, is sure to cause many “OMG moments”. Recollected here are five such moments I’ve experienced.
Brief Ruby primer
The most important thing in the programming language is the name. A language will not succeed without a good name. I have recently invented a very good name and now I am looking for a suitable language.”
Ruby ships with an interactive prompt (irb) which you can use to run code. Many of the examples here will include code typed directly into the interactive prompt rather than full programs. To give you a brief example; this is the command that prints the words “Hello World” to the console.
irb(main):001:0> puts "Hello World" Hello World => nil
where the “irb(main)” part is the command issued, and the lines that follow are the output. To microsoft guys like myself, this is like the “immediate” prompt in visual studio.
It would also help to have a basic knowledge of Donald Knuth. Actually that’s a lie. It’s just that I idolize the man and rails is the closest I think we’ve come to realizing the principles he established thirty years ago, So I’m going to scatter Knuth quotes liberally throughout this post (done one already, not sure if you noticed!). Hopefully even if you’re not a Knuthist you’ll at least possibly be inspired by the quotes.
Anyway, on to the OMG moments!
OMG Moment 1: Everything is an object
“There’s ways to amuse yourself while doing things and thats how I look at efficency.”
Yes: Everything is an object. There’s no such thing as a “simple type” here. 1 is an object, 3.141 is an object. Here, see the proof;
irb(main):004:0> 1.object_id => 3
irb(main):005:0> 2.object_id => 5
Yes, that was me calling one of the “1” object’s methods. If that didn’t freak you out enough, check this out. NULL (in ruby called “nil”) is the generally accepted term for “Nothing” in computer science. It is the absence of a pointer to any data. In Ruby, however, this is actually also an object!
irb(main):007:0> nil.object_id => 4
Yup, I called one of nil’s methods, and proved that it is an object by finding it has an object ID. Here’s one of its other methods;
irb(main):009:0> nil.as_json => "null"
This revelation was the first of the “OMG!!1!” moments.
OMG Moment 2: Code as documentation
“Let us change our traditional attitude to the construction of programs. Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. ”
Knuth’s principle of literate code is one I subscribe to heavily. Your code should read like a good book: in an ideal situation someone should be able to read it and understand exactly what is going on, because in an ideal world the code captures the logical process when you went through when you wrote it.
Unfortunately we don’t live in an ideal world. In programming, we are required to work with the syntax we’re given and that doesn’t always allow for us to express ourselves in a way that would be easy to follow for player two should he or she come along afterwards. In my own personal ideal world, the following IRB results will speak for themselves and anyone new to RoR will consider them an OMG moment too;
irb(main):010:0> 1.week.ago => Tue, 07 Dec 2010 20:29:14 UTC +00:00
irb(main):027:0> " Hello World ".squish => "Hello World"
irb(main):038:0> 1.kilobyte + 1.byte => 1025
squish? Yes – this represented my second “OMG!!” moment.
OMG Moment 3: Erm… did I just do that?
“Science is what we understand well enough to explain to a computer. Art is everything else we do.”
One of the things that rails has made very clear to me is that in using other frameworks, I really have spent a lot of time doing the same bloody things. Let’s do a quick list of things you generally do when you develop a dynamic website;
- I will need to connect to a database
- I will also need basic CRUD
- Probably gonna need some kind of object based model to represent the task, based on my database tables.
- I will need to validate user input
- Eventually I’ll also probably need a payment gateway
- and I need throughout to compensate for various security issues
- oh and I might need an API at some point…
- and so on
This list could go on, but in a nutshell RoR is aware that these are regular tasks and goes out of its way to basically do them for you automatically. To demonstrate this; consider the following three commands;
$ rails new testblog $ rails generate scaffold blogArticle title:string content:text created:datetime $ rake db:migrate
these roughly translate into;
- I’m making a new application called “testblog”, please prepare an environment for me
- Now I’d like to create the idea of an article, which has a title, some content and a date created.
- Now can you tell my database about it.
Those three lines of code give you this;
Not only do you have pages up and running, but the model already comes with it’s own API for free (you could browse to test-articles.xml and see your articles represented in xml).
Now, you don’t want to be using scaffolding (essentially, auto generated classes and such) in a production environment, but when you have a hungry and paying client to satisfy, an annoying sales or marketing guy who wants to see his ideas realized, or a designer eager to get on with the pixel-pushing, you can’t get much better than “three lines and your’e done”! Come on, would you prefer to spend a day developing a framework that’s not fit for purpose, or would you prefer 30 seconds work to get your assumptions up and rolling? No brainer.
This represented the third of my “OMG” moments.
OMG Moment 4: It’s stable and easy
“A list is only as strong as its weakest link.”
Arrays are represented by comma seperated values within square brackets. combining two arrays?
irb(main):001:0> [1,2,3] + [4,5,6] => [1, 2, 3, 4, 5, 6]
finding the first value in an array?
irb(main):003:0> [1,2,3].first => 1
The weirdest thing for me was this;
irb(main):006:0> [1,2,3].count => 3
irb(main):007:0> [1,2,3].length => 3
irb(main):008:0> [1,2,3].size => 3
Yup, three methods that do the exact same thing. Why? And after much deliberating the only conclusion I can draw is that when you’re reading your code back, sometimes each of the above will feel more appropriate;
Although this laps over a little bit into the last point, the stability of the language and the fact that you can test out your assumptions within the safety of a console were an absolute revelation to me, and this my fourth “OMH!h222!1!” moment.
OMG Moment 5: But I didn’t code any SQL yet…
“If you optimize everything, you will always be unhappy.”
When you approach a web application, you know you’re going to probably need a database connection at some point. As a programmer, this poses a few considerations;
- Which type of database am I coding for?
- I need to seperate this data access out in case the database type ever changes!
- I REALLY hate SQL, because it’s not Object Oriented, but I guess it’s what I’m stuck with .
- And OH THE SECURITY!
RoR introduces the concept of database agnosticism and migrations. You basically write your database schema in ruby, and then “migrate” it into the database of your choice. Database type is thus turned into a configuration issue rather than being a coding issue. To show this as an example: consider the test-blog application from the last point, if using the default RoR settings, would spawn itself as a SQLite database.
All it would take to change that to a MySQL database would be to edit your database config file. This comes in the form of a .yaml file (yaml being the recursively named syntax ‘Yaml Aint Markup Language’). This not only gives you the ability to connect to other data sources, but also allows you to develop under the SQLite environment (which you get out of the box) and then once you’re done you can easily port your application over to a real environment.
The main point being that your code DOES NOT NEED TO CHANGE! This insanity represents my final OMG moment (for the time being, anyway!).
I am, and will always be, a follower of eveything Microsoft do. In the UK, you have to if you want to remain employable. If someone presents you with a legacy back-office system that you need to hook into, and that is based on Microsoft technology, the last place you want be looking to is RoR. However, for new or home projects RoR is well on the way to becoming the framework of choice.