Lately I’ve had some interesting random conversations with lots of folks who do a fair amount of hiring. Recruiters, HR folks, etc. Basically the analysis was that there’s really not much Triangle/RTP job market for Ruby outside of web site development — there is some, of course, as I know some friends who are doing it, but it is still very small. Meanwhile, I’ve had 2 almost-exclusively-Python jobs here and am about to have a 3rd. I’ve come to a few conclusions that the Ruby crowd (via ycombinator, reddit, etc) is perhaps just exceedingly vocal. Given, there are a lot of serious projects in Ruby as well (Puppet & Chef, obviously), and there’s nothing wrong with picking something new and what you like best. Here’s my take, after doing a lot of Python, and some various (unsuccessful) attempts at Ruby to seduce me long term:
(Aside: we’re still a huge Java/.NET market here, and being able to work in something else I’m glad is still possible, and for the same reason, I’m really glad the alternative-JVM language space is heating up).
Things I like about Python:
* lots of traction in enterprise computing (Canonical, RH, Zenoss, OpenStack, Google, etc…)
* strong amount of modules available for a wide variety of tasks, many widely already packaged in your Linux distros
* first-class functions without having to wrap them in a Proc
* less syntax, indentation system, and ability to leave off trailing “ends”
* code written the first time is often the final version and doesn’t have to be rewritten
* very readable to non Python developers, easy to encourage them to pick up the language to patch code (well proven!)
* indentation system allows things to be more skimmable versus code on same lines, etc
* list comprehensions
* in the web space, Django’s built in admin views are awesome, and it’s very stable/compatible
* no trailing if/unless (I sometimes like it when I do it, but often not when other people do it, so that means I shouldn’t like it)
* feels minimal
* nice C API
This I don’t like about Python:
* the regex module (though I more or less agree it’s best to not use regexes when you can) is a little weird
* eggs and easy_install
* raises exceptions on error conditions versus returning None a little too much (hash['foo'] vs hash.get(‘foo’,None)), which makes code more complicated
* docstring syntax versus just commenting with “#” (minor)
* occasional inconsistent core library usage of CamelCase and with_underscores
* having to manually specify self (minor)
* map/lambda syntax is a little crippled, but I’m starting to agree with Guido about list comprehensions being better and that named functions are important
* a few functions that operate on duck typed things versus being methods (len, etc)
* somewhat confusing jumps between views/iterators and things that return lists between various versions of things
* unicode has been annoying in the past (basestr, etc)
Things I like about Ruby:
* block syntax can be fun
* has the regex module from Perl, more or less
* built in classes like Array have lots of useful methods
* can often be more concise in terms of chaining functions (which can also be bad)
* rspec has some clever capabilities
Things I don’t like about Ruby:
* “module of the week” mentality… 7 different libraries for Markdown conversion, Passenger vs Unicorn vs Mongrel vs…
* Proc to get the equivalent of first class functions
* very web development centric culture, almost one and the same with Rails, if you’re not a web developer
* culture can get too obsessed with how pretty the code looks versus larger problems
* tendency for modules/tools to monkey-patch other modules, which is reckless
* gems
* lack of namespaces
* confusing changes between versions
* foo! and foo? syntax — it’s hard to remember what modules have it and which don’t
* way too much syntax in general
* attrs and implicit behaviors thereof, I just don’t like them
* trailing () on functions are optional, making it hard to tell what’s a function and what’s an attribute
* typing out “end” reminds me of basic
* syntax errors from compiler error messages are often poor, gets confused about what line something is on
* If you’ve seen Perl’s MooseX::Declare, and write to best practices, it’s not much more than Perl.
* “:” to get symbols
* implicit returns
Ultimately we all have to use eleventy billion different languages, and can’t always work in the ones we like. Nothing’s perfect, though some things fit our brains more than others. Anyway, I tend to see a lot of posts from the Ruby crowd, and I think the Python crowd is more quiet… probably because we’re working on different things (in the Rails case, I mean, less of it is about web applications), or maybe because we just like to think differently — my first real job was a lot of C. Often apps have to support things longer, and are less interested in change. It might take a bit more to excite us. The likelihood is it’s the application that’s interesting, not the code behind it, while I think the Ruby crowd is very enamored with the code layer. I’m interested in what I can build out of it, and how easy to maintain that is. I want it to be very easy to work on, but when I’m away from something, I want to think about the capabilities, not the lines of source. So, to my brain anyway, the tool that allows my to write something high-level that’s exceptionally readable several years later is the one I want, even if it doesn’t tend to encourage exciting code manipulations. Individual lines of code and how clever I can make a map/inject/block-thingy… not so much. It also seems with Python there’s a bit more of a “to the metal” feel of things, namely if you want to get inside the classes at a very low level, things like metaclasses allow for a nice level of exposure into the internals… but only if you do need them. That’s pretty cool, I think.
Python might be nicer if it had blocks, but I think in 95% of the cases, “with” and “list comprehensions” are good enough, and that keeps things simpler. I also mostly find my blocks usage is usually limited to each (which list comprehensions handle) and the occasional transaction like call (which “with” handles), so I should quit letting myself be seduced by them. Python lets me maintain the whole app easier, IMHO, and if I’ve got one function or two that is not entirely beautiful at the source level, that’s not a major concern, because most of it is… and it’s obfuscation resistant, making it work much better in group contexts.

