For the last 2 months, I’ve been using a new Ruby framework at work. A very… interesting framework :) It looked very promising in the beginning, only to become a complete disaster a few weeks later. I thought I could share some of my experiences with it here, although not to recommend it, but rather to warn you not to use it…
Its name is Hobo, which makes most people think of homeless people, and makes it a constant object of jokes in my company (see below :)…
A sign hanging in my room – copyright by Wombat
So, what does it do exactly? It does several different things:
- Smart (in a way) permission checking; all you need to do is define a few methods in each model class –
updatable_by?and so forth – which tell if a given user can perform a given action on the object, and that’s basically the only place where you need to be concerned about permissions – Hobo infers lots of information from these methods and uses them everywhere.
- Auto-generated migrations; fields are defined inside the model (like in DataMapper) in a
fields do ... endblock, and it generates migrations automatically for you, detecting which columns or tables were added, removed, or changed since the last migration. You can update the migrations manually before you run them.
- Automatic controller actions. This is how a default controller looks like:
class FilesController < ApplicationController hobo_model_controller auto_actions :all end
And it’s fully functional – the
auto_actionscommand tells it to use the methods in
Hobo::ModelControllerclass, which do such stuff as fetching necessary objects, checking permissions, validating records, saving, redirecting and printing default flash messages. If you need some extra functionality (and you usually do, though not always), you can call the methods in such a way that you only add your extra lines and the rest happens as before.
- Automatic routing – all standard routes are auto-generated based on controller actions, you don’t need to touch the
routes.rbfile unless you need something non-standard.
- A new template language, DRYML (DRY Markup Language). It consists of XML-like tags, which internally work like Rails helpers; you can (or rather should) define your own tags in files called taglibs, and there are literally hundreds of tags in Hobo’s taglibs. Also, the more advanced sets of tags are intended to let you write pretty complicated things, like AJAX-ified fields and forms, using just one or two tags – this is what the “rapid” part is about.
Why it won’t work
Looks awesome, doesn’t it? Yeah, that’s what I thought too. So where’s the catch? There are two.
The first is that although it would seem that Hobo makes development much much faster, it really doesn’t. It has a steep learning curve and you need to spend a lot of time to just get started, if you plan to write anything more complex than a default scaffold interface. After a week and a half, the only thing that I’ve managed to write was redesigned registration process… And although it gets better, even after a few weeks you still spend a lot of time digging deep into Hobo code, trying to find out how to use a controller action in a specific way, which one of the hundreds of tags you should use and how, or why the hell does it throw that exception when it shouldn’t (and the reason is often that it’s just a bug or that this is one of the 10% cases when the Hobo magic doesn’t work).
And I’ve left the best for the end… It’s SLOW. Really f***ing SLOOOOOOOOOW. In the development mode, it takes between 2 and 5 seconds to load a page. I thought it was just because it had to parse the DRYML tags each time, and that in production it would be fine. It wasn’t. Sometimes it takes as little as 30 ms, and sometimes you get something like this:
Completed in 1.01311 (0 reqs/sec) | Rendering: 0.96372 (95%) | DB: 0.02360 (2%) | 200 OK
That’s 0 (zero) requests per second… in a normal index action that just lists objects. That’s exactly ∞ times slower than a normal Rails application ;) (I know, it’s just rounding, but it looks funny. or terrifying, depending on how you look at it…). This also means that if your users send a request to the server every 10 seconds, you need a separate machine for every 10 users… o_O
It took me a few weeks to realize that Hobo is just designed in such a way that it can’t run fast. It’s not a matter of implementation which can be optimized, it’s a matter of starting with wrong ideas at the beginning. Like the idea that you can define permissions in methods in a model, and then call these methods a lot of times for every single object that you want to display. Hobo does a lot of things for you, it’s really smart, it can determine thousands of details by itself without your help; but because it needs to check those thousands of details in every request, it must be slow, and will always be slow…
So, the bottom line is: even if you thought this was cool at the beginning, don’t use it. Seriously. Unless you want to end up as a hobo and eat hobo soup… ;)