Ruby and Rails for Attractive .NET Developers
December 18th 2010Warning: This post might not be any good. These are my personal observations of using Ruby and Ruby on Rails after about six weeks of use, which means: (a) In a similar way to a Chemistry degree freshman in their first semester realizes that everything they were ever taught at High School was actually a lie, I await all my mental abstractions to come tumbling down and (b) I am still at the theme park ‘Wow, that ride was Awesome!’ level of objectivity, and this post is being written from the gift shop you must walk through on the way out.
Here’s some of my observations so far:
Expressive. Ruby is expressive. Jim Carrey on amphetamines dressed as a French mime playing charades acting out ‘Oklahoma!’ level of expressiveness. It absolutely loves strings, and isn’t embarrassed to acknowledge that the reality of most programming tasks is to endlessly shuffling around characters. The String class has at least 4E24 methods (exercise left to reader). The evil genius of regular expressions has been institutionalized to the extent that you can use them directly as literals, which depending on how comfortable you are with regex expressions, is either a blessing or a Tourette’s Syndrome glimpse into an otherwise very natural language code reading style. @@_x =~ $& isn’t a cartoon expletive, but is often how I say it out loud.
Ruby’s names allow you to travel fully over a modern keyboard – you can using characters like ? and ! in method names to indicate intended behavior. It’s a language where you can express your intent in English, albeit someone who occasioning splutters too many secret symbol combinations. The code is typically terse but very readable once you get past the initial learning hump. The language’s reserved words set is very small, but you do get the feeling that as each new idea has been added, and with the internment of regex, that every non-alpha symbol is destined to be special. If you ever gave up on vi or vim without even printing out a cheat sheet then you may find Ruby initially awkward.
Idioms. Ruby has more idioms than Hans Christian Andersen’s grandmother. It has a strong sense of style that is encouraged rather than enforced. Ruby is an adult-orientated language, in that you can tell it has been developed by people who have really lived in the clothes of other languages and want to improve. It is unusual to read really bad Ruby code, and it’s surprisingly consistent given its flexibility. I’m not sure why this is, but would guess that it’s a ‘Second Marriage’ attitude of many of the community, in that Ruby is not their first time around the block. Blocks and closures allowing behavior as a first class objects, method-as-message passing attitudes around duck typing and enumerations rather than outside loops all contribute heavily to the feeling that what is considered high-falutin' CS concepts in other languages are now mainstream normality here. If you are a C# developer that hasn’t internalized LINQ yet or a Java programming who couldn’t describe generics without a Google search then Ruby is either a great new opportunity to reset or a potential house of horrors depending how much you want to bend your brain muscle.
Useful Introspection. Reflection and the VM environment are two areas that are worth highlighting in Ruby. (As you probably have gathered by now, this isn’t a tourist language tour, it’s more of a random postcard – I recommend this if really want something authoritative to read here). If you are used to a half-static language then it is disorientating to see how introspection techniques are used in real code. The first time in Rails you see something like this:
find_by_username(user_name)
..and then realize it’s a dynamic finder that relies on a method_missing to go look to see if ‘username’ is an actual ORM attribute before turning the expression to
find(:first, :conditions => ['user_name = ?', user_name])
..was a happy moment for me. Ruby is the Domain Specific Language run-time that I’ve always wanted.
Note: Rails especially loves symbols (that :first name thing above) as they make great hash keys amongst other things. A symbol is an interned string (made unique in a map) often used as a ‘lookup’ to an existing identifier. More real info here. I’m not sure why Ruby doesn’t have named parameters yet (See disclaimer up top on my ignorance), but the language certainly seems alive and active, in that perhaps the next version will?
The monster in the closet of all this dynamic evaluation and duck typing has often been touted as performance. This is, in my opinion, a fallacy. Your developer environment and production environment are not the same, nor should they be. They serve two separate purposes and can run in very different and specific ways. Ruby and framework’s like Rails re-enforce this separation. It is hugely productive to be able to alter your codebase while running your code in development – and if you’ve ever made a cup of tea every time you compile a large code base you should understand exactly what I mean here. When you deploy to production your run-time should match your needs, but not as a developer. This evaluation of dynamic finders time will not be significant in a realistic production run-time if your application is doing something non-trivial. Measure, don’t guess or assume. Let go of any prejudices.
The concept of compiled executable images being performance profiled on your desktop machine, and the language bottlenecks showing up like flies to swat is not helpful anymore. Whether your target is web, mobile or actually even desktop, relying at a language level intuitive measurements for performance is a mistake. You can write bad or inefficient algorithms is any language, sit waiting on a read access for too much unfiltered data – you don’t need Ruby to do that for you.
Rails. Rails is really Ruby’s significant other and the main gateway drug to active Rubyness due to it being a big ol' lump of real-life Ruby to go stare at and see working. I write web apps, and what I want to do fits well with how specifically Rails tries to solve that problem. The real ‘Rails trick’ seems to be understand first what Rails is meant to help you with before committing to it. It’s not just a DSL for making a blog in 15 minutes or even a twitter clone, but nor is it as general as you might think – make sure you want to walk this path, as fighting it isn’t fun.
The most pleasant surprise so far for me in Rails-land has been the active Gems community. This open-source extensibility attitude is probably the single most productive enabler for me around Rails at the moment, in that I spec up a feature I need and then often find anything common enough available as an existing engine, gem or plug-in.
If you come from the Microsoft world this is a refreshing thing to see, in that these ‘components’ (for want of a better word) are chiseled by real world use, born out of a realistic business need and have to survived the Darwinian process of selection in the big wide world. Bad or useless code of course exists, but that can just be ignored or not forked. Good things bubble up, bad things are not made into must use ‘corporate standards’. The ecosystem is also very varied, and not focused on one particular tier i.e. ‘UI Grid Component Version X – Now For UI Technology N+1!’. A lot of the ‘aspects’ side of a system design have been offered as extensions, in that you can reuse gems for database models (Active Record over NoSQL solutions are fashionable in that ‘Look Ma, No Disk!’ kind of way), as are things like authentication, authorization, markups and logging and the like. Rails 3 has made significant in-roads into extracting itself from all-encompassing design decisions in these areas and the raw choice is impressive. A few years ago it would have been ok to say that Rails and it’s extensibility captures the architectural patterns in ways that formal top-down authoritative-style frameworks have repeatedly failed at, but the naughty ‘Big A’ word has far too many connotations nowadays that I’m too afraid to use it.
Home Is Where The Shell Is. The natural developer home for Rails seems to be a Mac. More specifically, a brand new Mac Airbook carried in a European soft-leather carry all containing an expensive men’s face creme, a Lonely Planet’s Guide to Reykjavik on $10 a Day and an iPhone 4 filled with 16GB of smooth sweet jazz. Either that or any distribution of linux works fine too. My main point here (other than a backlog of Rails stereotype jokes I can’t do anymore) is that Windows is not its natural environment – you can probably get it to work fine in the end but expect some needless nailing of jello to walls. If you are curious but on Windows then I can recommend either VirtualBox or just use Wubi till you want to create another partition – they are all good. O/S’s all work the same (Discuss: 20 pts), and you will survive without intellisense (and yes, there are ruby IDE’s that do this too). Embrace your inner vim/emacs.
So far I’m on my second semi-major Rails web app and an important side of these first thoughts is that I’m still enjoying the whole environment enormously. The code I write is specific to my problem domain, which I think is where we all need to be heading.
It is interesting in that a lot of the ‘magic’ side of Rails is actually not that mysterious at all, in that it follows the idioms of Ruby and that whole stack is still vibrant, changing and moving forward. At times it seems chaotic, but I think that’s part of why it’s still alive and kicking. So far so good.