View Rahoul Baruah's profile on LinkedIn Basecamp project management and collaboration

The blog of Rahoul Baruah from 3hv Ltd

What's going on?

My name is Rahoul Baruah (aka Baz) and I'm a software developer in Leeds (England).

This is a log of things I've discovered while writing software in Ruby on Rails. In other words, geek stuff.

However, I've decided to put this blog on ice - I would ask you to check out my business blog here (or subscribe here).

03 March, 2008

See ya



I started this blog over two years ago, charting my experiences using Ruby on Rails on IIS.

As you may have noticed, I don't do that anymore. Not that I have any great hatred for IIS/Windows/Microsoft - it's just not as much fun as staying on the Linux side of the fence.

While I still love coding in Rails, I'm not doing that much out of the ordinary any more. All the interesting stuff is at a business level - so instead I'm going to concentrate on my business blog (you can subscribe here if you want). There'll still be Rails stuff posted there, but intermingled with marketing, sales and finance.

So thank you Blogger, thank you IIS, thank you dear readers. It's been a blast. See you at 3hv.

08 February, 2008

The Return of Django

I see the Django folks have been hitting my "Installing Rails under IIS" article pretty hard recently.

All I can say is "good luck guys" - I'm glad I don't have to do that at the moment. Did MS ever finish their FastCGI implementation?

Spamming Northpack for fun and profit

Leeds Ruby Thing was last night - it was a fun night out with a good number of people (about 20-25 turned up). John has posted some photos.

But mainly this post is to annoy Dominic when it appears on the Northpack feeds list.

06 February, 2008

What's wrong with RSpec?

I don't know.

I've tried, really tried to like it.

And I don't know why I don't.

Something just doesn't feel right.

  • It's testing.
  • It's test-first.
  • It's test as specification.
  • It reads like English.

All things I like.

But it feels wrong, wrong, wrong.

Anyone have any ideas why?

PS: I was going to call this post "Arse-pec" but I thought that was a bit harsh.

ASCII changes cause strange artifacts

Why does Squeak use the underscore _ as an assignment character[1]?

Because in 1963 the ASCII code for _ actually represented a left arrow - which makes perfect sense as an assignment operator.


[1] (as well as := which Pascal folks will recognise)

04 February, 2008

The Leeds Ruby Thing

Expertly named by £2000/hour marketing consultants, the Leeds Ruby Thing is taking place at the Victoria Hotel at 7pm on Thursday the 7th February. I probably can't get there till 9ish though.

Join us and talk about Ruby. And drink beer.

03 February, 2008

Microhoo!

I stopped reading FSJ a while back but he certainly has the best analysis of the proposed Microhoo! deal I've seen so far. It's also worth noting that nothing has actually happened yet.

Via Imran Ali on Twitter.

30 January, 2008

Dominic

Dominic "The Hodge" Hodgson is doing an SEO experiment - aiming at 26 in Google. So this post is for him.

Why hashes as named parameters in Ruby are a good thing

Back when I used to do lots of Sql Server Transact-SQL, I used to dislike named parameters. They annoyed me and I only used them when I had a stored procedure with a large number of parameters, some of which were optional. (As an aside, we had procs with parameter lists running into twenty or thiry, some of which were optional and some were mandatory - it was a nightmare and named parameters were essential in those cases).

Odd though. Named parameters turn out to be one of my favourite Ruby features - even though Ruby doesn't have them. And, even odder, they used to be one of my favourite Smalltalk features (Smalltalk has always had them).

Today, my learned colleague was on a roll. Fantastic design ideas were flowing. One issue he was busy solving was handling an image at multiple sizes. The application had an ActiveRecord class representing a file - and if the file were an image then it could store that image at multiple resolutions. He proposed something along the lines of this: my_file.required_size(width, height) - the implementation would then hunt through the related images at various sizes, pick out the correct one and return it. This meant that a view would have code looking something like this:

image_tag my_image.required_size(400, 300).web_url, :alt => h(my_image.description).

His proposed implementation was fine - but I suggested renaming the method at - so you could write my_file.at 400, :by => 300.

"But at doesn't explain the method's purpose" was the reply. "That's why you should name the second parameter and pass it as a hash" said I. This would make your view code look like this:

image_tag my_image.at(400, :by => 300).web_url, :alt => h(my_image.description)

Personally, I think this is much easier to read and, with the named parameters, explains the intention of the at method perfectly (although the brackets spoil it a bit).

The key difference between the two languages is that in Ruby, the method is named "at" and you call it as my_file.at 400, :by => 400. In Smalltalk, methods names include the parameters - so it is named "at: aWidth by: aHeight" (and you would call the method by writing myFile at: 400 by: 300.).

The Smalltalk idiom of including the parameter names within the method name is much clearer at explaining the method's intention. And the very act of naming your parameters means you can apply much more meaningful sentences within your code - which is exactly what Alan Kay meant for us to do all those years ago. Don't you agree?

28 January, 2008

Brightbox at NWRUG

Jeremy and John will be speaking at the North West Ruby User Group tomorrow (Tuesday) about the business and technical challenges of setting up a UK Rails-specific hosting company.

23 January, 2008

Moving changes from one subversion repository to another

I'm sure this is old hat to you svn experts but I've just figured it out.

If you need to transfer a load of changes from one subversion repository to another (or you have an external developer helping you out on your open source project who has submitted a patch) this is what you need to do:

Generate a Patch File



Move to your "source" working copy and run:

svn diff -r REV > my_patch.txt

This finds all changes since revision number REV and places them in my_patch.txt.

Apply a Patch File



Move to your "target" working copy and run:

patch -p0 < my_patch.txt

This applies all the changes in my_patch.txt to your target working copy. Running svn status then shows all the files that have changed - you can then review the changes before an svn commit (of course crediting your developer in the comments).

17 January, 2008

A (late) review of the year

It's been a pretty monumental year for me - quitting the day job and doing this Rails business full-time. Plus, I've actually been blogging about it. So, a bit late, here are my favourite posts from last year.

unless versus if ! (absolutely the greatest piece of example code there is)
Great Features you see, Great Features you don't
markup.become(:beautiful)
Death to Professionalism
Dealing with Disaster (Dreamhost take note)
form_test_helper and AJAX (Update)
Ruby on Rails is the MacOS to Java/.Net's Windows
The infamous iPhone SDK
Testing for Unix commands on the path in Ruby
Safari, So Good, So What! (just for the title, Megadeth fans)
Default Values in your Models (one of the most searched for posts on the blog)

Geeeeeeeek Uuuuuuuup

Another Wednesday in the middle of the month, another Geekup meeting in Leeds.

I had a great time chatting with the Brightbox boys and taking photos of the Northcrew, in preparation for the launch of their two new sites - Northcast and Northpack.

Thanks, as ever, to Deb and Rob for organising it. And the next one has Christian Heilmann talking about Javascript.

07 January, 2008

10 Rules of Thumb to radically improve your Ruby on Rails code


Ruby on Rails has generated a lot of hype over the last couple of years.

This is a good thing - Rails is well-supported and well-understood.

But it's also a bad thing.

Lots of people read the "Agile Web Development" book and then charge a fortune to develop RoR applications. Badly.

I have seen some shocking projects, chock full of the type of spaghetti code that the Rails hype claims you cannot produce (of course this is nonsense - you can write shite in any language).

Over the years I have developed a whole number of "rules of thumb" that I use to evaluate a project's code. These are subjective, inaccurate and open to interpretation. But taken as a whole they give you a pretty decent idea of the state of the code.

And here they are:

rake stats

Look at the ratio of code to tests.

  • More code than tests? Lose 10 points
  • Between 1:1 and 1:1.5? No points
  • Above 1:1.5? Gain 5 points
This test is pretty arbitrary. Just because you have lots of test code doesn't mean that the tests are any good. But not having lots of tests is bad.

Dependencies

Is Rails and any required plugins installed into the vendor folder?
  • No? Lose 10 points
  • Yes? No points
It's incredibly easy to include the correct version of Rails and all your dependencies within your application tree. Making it easier to share your code with the rest of your team and taking uncertainty out of deployment.

rcov

Is rcov pre-installed?
  • Yes? Gain 5 points
rcov is easy to install and pretty useful.

What is the test coverage?
  • rcov won't work? Why not? Lose 10 points
  • More than 10% red? Lose 20 points
  • Less than 10% red? Lose 10 points
  • All green? Gain 10 points
This test is also pretty arbitrary. A green line, as above, doesn't mean that the test is any good. But a red line is always bad.

Migrations

Can the database be built completely from migrations?
  • Yes? Gain 10 points
  • No? Why not? Lose 10 points
Databases are key to Rails development and migrations make them easy to share with your team and deploy to your server.

Logic in all the right places?

Is there any application logic in the controllers?
  • Yes? Lose 10 points
  • No? Gain 10 points
Controllers are part of the user-interface, function specific and relatively difficult to reuse. Application logic belongs in the models where it can be accessed via the console, not just the web-server.

Is there any application logic in the views?
  • Yes? Lose 10 points
  • No? Gain 5 points
Views are strictly user interface components - they should be primed by the controller so that the view has nearly all of its decisions made for it.

Warnings and Deprecations

Are there any deprecation notices when running the tests or application?
  • Yes? Lose 5 points
Deprecation warnings mean that your code will probably stop working when you upgrade your version of Rails.

Are there any warnings when running the tests or application?
  • Yes? Lose 20 points
Warnings are there for a reason. Pay attention to them - in most cases, it is purely laziness that keeps them there.

RDoc

Do all the models have RDoc comments - a header describing the class and comments for each method?
  • Header comments? Gain 10 points
  • All method comments? Gain 10 points
  • Some method comments? Gain 5 points
  • No? Lose 10 points
Do all the controllers have RDoc header comments describing their purpose?
  • Yes? Gain 5 points
  • No? Lose 5 points
Do all the helper methods have RDoc method comments describing their purpose?
  • Yes? Gain 10 points
  • No? Lose 10 points
Ruby is easy to read and generally pretty easy to understand. That deals with explaining what your code does. But the point of the RDoc comments is to explain why it does it that way, which, arguably, is even more important.

Repeated Code

Is there any repeated code? Are there similar pieces of code in multiple places that could be consolidated into a single parametrised method?
  • Yes? Lose 10 points
When writing code if you find yourself writing something similar to code you have already written then it is always worth moving it into a centralised method or class - either as a helper, a model or even a module.

Readability

How readable is the code? Can you tell, at a glance, what the most complicated pieces of code do?
  • No? Lose 20 points
  • Yes? Gain 20 points
Unfortunately this one is pretty subjective. But, to my mind, code should read like English wherever possible. This may be sub-optimal - especially with regards to performance. It doesn't matter. You can go back, profile the code and optimise the slow bits (of course, your tests make sure that you aren't breaking any functionality). And when you optimise, keep the original (slow) code as a comment to explain what your unreadable (fast) code is doing.

Idioms

Does the code use symbols as hash keys and (the equivalent of) enumerations?
  • Yes? Gain 10 points
  • No? Lose 10 points
Symbols are sort of like strings but are treated specially by the interpreter - sort of like a literal. Carefully used, they can also make your code more readable.

Does the code pass objects to generate links?
  • Yes? Gain 5 points
  • No? Lose 5 points
HTTP is not object-orientated but Rails can at least pretend that it is.

Writing this stuff down is strange. It takes things that often comes to me as a "gut feel" and documents and codifies it. Necessarily this means that there are things that I notice that I haven't written down here. Apologies - I will update the article as and when I think of them.

What use is this check-list?

If you are worried about the state of your Rails project 3hv is planning a service where your code is evaluated against these criteria and you receive a detailed report with recommendations for improvement. Excellent for managers who are worried about progress, even better for developers just starting out on Rails. Details are still being finalised but contact me if you are interested.

30 December, 2007

Coding in English

I've been programming computers, professionally, for over eleven years now (and programming in general for over twenty). In that time, I've tried a number of different programming environments and languages.

Delphi (Object Pascal),
Java (upto 1.4),
Smalltalk,
Ruby,
Python

and

C#,
Visual J++,
VBScript/Visual Basic,
Realbasic

as well as

Ansi C,
C++ (Borland C++ Builder, Visual C++, Ansi C++),
Objective-C (only a little bit),
PHP,
Lisp (at least some variant of it that was designed by someone at my university),
x86 assembler.

The languages and environments I like are in the first group, the ones I dislike in the latter group and the middle group are "almost but not quite". The question is what do they have in common?

Simple: it is easy to make them read and write like English.

Yeah, it's a bit subjective.

You could argue that Java and C# belong in the same group (I'll get to that in a bit). But the last group are quite happy chucking weird syntactic pieces into the mix - it makes my head hurt trying to remember when you need a & and when you need a * in the C languages. I have to say that Ruby, at first, put me off with its @s and @@s.

What about Java and C#? It has to be said that syntactically they are both very clean. But why is Java in the "good" group and C# in the "maybe" group? Because when I met Java it was cleaner than everything except Smalltalk. But when I met C# my frustration with static typing had boiled over. By the same token, Delphi now belongs in the "maybes" whereas, at the time, it was firmly in the "goods".

But, overall, Ruby wins. Code like:


dave.punch george unless george.is_hard?
(I'll never tire of that example).

Or:

using :lame do
encode '/my/audio/file'
end
(a real bit of code that only executes the block if the given the 'lame' command is present within $PATH)

Or:

hit nail, :with => hammer, :on => head, :at => :maximum_force

The latter is a pattern I often follow - using Ruby's hash as a way of building named parameters. This is something I learnt from Smalltalk, which was originally intended to be usable by seven year olds (hit: theNail :on theHead :at #maximumForce.). This makes the method definition look something like:

def hit object, options = {}
using = options[:with] || my_default_implement
where = options[:on] || my_default_area
force = options[:at] || my_default_force
... some code ...
end

The key thing here is that the options keys do not match the actual variable names because they serve different purposes. The options keys are for the users of the method, the variable names for the implementors.

Likewise, Ruby's arrays combined with blocks give you a whole load of power in a very small amount of text.

Given the choice of using Array#inject or writing something more verbose I will always go with the verbose.


collection.inject(0) { | sum, obj | sum += obj.details.size }

versus:

total = 0
collection.each do | item |
total += item.details.size
end
return total


(OK - not the best example). But, to me, the intention of the second version is immediately apparent whereas the first takes a second of squinting to figure out.

I was recently presented with something looking something like this:

sort{|a, b| index.collect{|i| (a[i] || 0) <=> (b[i] || 0))}.compact[0] || 0}

With apologies to the author, I'm still not sure what that does.


Readability is everything. Code spends longer in maintenance than development. And choosing your tools correctly can mean that, with minimal effort, your code can look like English.

29 December, 2007

Nostalgia ain't what it used to be

I gave away my iMac G3 a few weeks back. I wiped all my personal details off the machine and gave it to Freecycle. But in order to wipe my personal details I had to boot it into OS9 - and it has to be said that it's still better than OSX.

A 500Mhz 512Mb G3 is more responsive (not necessarily faster) than my dual 2.3Ghz 2Gb MBP.

The consistency of the UI, the simple rules (start at the top left and flow to bottom right - which is why the Apple menu and trash can are where they are) and the fact that you had acres of screen space at 1024 resolution.

I miss both the machine and the OS. Sometimes progress isn't all it's made out to be.

21 December, 2007

Test Driven Development

TDD is quite easy. Write the tests first, make them pass, refactor. So why aren't you doing it?

Shameless self-promotion

Some people have recommended me, so the 3hv site has been updated accordingly.

20 December, 2007

Geeking up

Thanks to Deb and Rob for another Geekup. Weird beers, an iPhone and geektalk.

17 December, 2007

8 steps for fixing other people's code

How to submit patches to other people's projects.

And, of course:

If the project has a suite of test cases, please make an effort to add “failing test cases”. That is, add test cases that demonstrate the defect by failing

eXTReMe Tracker