I’ve been a long-time Ruby developer and more recently have been doing a metric ton of Python work. My goal with this post is to compare the relative pros and cons of each language as I’ve seen them. This was a difficult post to write, because of the deeply subjective nature of the question; like many other things in our industry, language preferences come down to something more akin to fashion or stylistic preferences than anything else. Still, I think there’s value in at least starting the conversation comparing Python and Ruby.
First, let’s get some potential caveats out of the way. Python for the purposes of this post means Python 3 and up. While my primary goal is to compare the languages, I am not going to shy aware from frameworks; in this case, that means Rails and Flask for Ruby and Python respectively, because that’s what my primary experience is in. Django developers, in particular, might find this choice a little odd, because of course, Django is a better one-to-one comparison to Rails than Flask. The reason I have chosen Flask to discuss is that’s where I have more experience. Having said that, both Django and Flask use SQLALchemy, which is where more of my focus will be and compares directly to Rails’ ActiveRecord. I am intentionally not going to discuss beyond to say that both Python and Flask have great selections of tooling available for developers on all major operating systems; in other words, the level of tooling is so similar as to be nearly moot for the purpose of comparison. Readers looking for this to be a boxing match with a clear knock out are going to leave disappointed. Both languages go the distance as far as I’m concerned. Coder Radio listeners might recall that I resisted learning Python for years, because I felt that it solved the same problem as Ruby. That more or less proved to be wrong and the passage of time and in particular the rise of IoT and ML hammered that point home for me.
Both languages allow for object-oriented programming, but Ruby is a strictly pure OO language. In Ruby, everything is an object full stop. Python isn’t as strict. This has some real-world implications for how you architect your code if you are a library developer, but for most regular web developers doing run-of-the-mill web applications, there will be little to no impact in most cases; that’s not to say it will never matter, but it’s just not something that needs to be front of mind. Python’s flexibility does make writing quick maintenance or management scripts in feel a little brisker. It’s actually gotten me to change from doing my scripting in Ruby to Python, since I find a little easier to be quick and dirty in Python.
Performance is frankly not a strong suit for either language. Both are interpreted and have roughly the same performance characteristics. There’s not a lot of value in my opinion in fighting the battle of which has better performance since there’s a lot of things that can affect it. Again, this one is a draw and if you actually care about performance you probably want a compiled language anyway. In both cases, you are making the classic trade-off in favor of developer productivity over performance and that’s usually the right choice for most projects; RAM is cheap these days after all.
I mentioned before the allure of diving into Python for me was the wide and varied applications for the language. In particular, the growth of IoT and ML as well as various data science fields have skyrocketed Python’s popularity. This is reflected in the usage stats and I also have some anecdotal evidence in my own family; a cousin of mine is a meteorologist who had to learn Python for her job because that’s the standard used by scientists of all stripes to deal with data. Ruby has not to date made significant inroads outside of web development; RubyMotion people, I await your fury. There’s a reason this happened, Rails. The vast majority of people who bothered to learn Ruby are like me, they went out with the intention of learning Rails. Over time, the Rails community became such as the massive majority of the Ruby community that it in effect became the Ruby community. This sounds controversial I know, but maybe I can make it clear by analogy. Down here in Florida, we have many invasive species of plants (animals too) that were incorrectly brought here. Sometimes what happens is that an invasive plant will be so successful that it crowds out native plants, starving them of sunlight and other nutrients. Rails is the invasive plant, starving out other Ruby projects and consuming the scarce resource that is the top and most experienced Rubyists; yes, I am aware that Rails is not foreign to Ruby, but other than that detail the ecological analogy holds up. With that in mind and out of an effort to make this comparison a little more one-to-one, I am going to start with an MVC stack from the bottom up.
Both languages have powerful ORMs. In the case of Ruby, it’s ActiveRecord and in the case of Python, it’s SQLALchemy. Both are fully featured powerhouses, but there is one difference that makes me really love SQLAlchemy, how it handles database fields for model classes. Take this simple example from Rabbot:
This is the SQLAlchemy version, notice that there is a straight-forward breakdown of all the columns on the backing database table for the model. I find myself often referring back to model classes when working in Python. ActiveRecord handles this a little differently and frankly, I find it somewhat obtuse:
Notice that there are no database columns or even explicitly listed in the class. To find these values we have to go to the schema.rb
file:
Sure that provides all of the same information as the Python version, but it’s just a little harder to read, especially because the data types used are those from the data (Postgres in this case) rather than the native Ruby ones; please note the slight differences between the models themselves are because they are actually different in the different versions of Rabbot. To be fair to ActiveRecord, if you’re using something like RubyMine or Visual Studio Code, IntelliSense will be able to figure out the properties and the correct types for you, but there’s something about having it right there in the model that seems more intuitive to me.
Moving from models to controllers in our MVC pattern, we have Blueprints and Controllers for Python and Ruby respectively. Both of these are good as far as I am concerned, but I do like how Rails (ie Ruby) puts all the routes in routes.rb
and makes adding a route simple; to be fair to Flask (ie Python) adding another Blueprint route is just a little more ceremony but comes with a nice structure that feels very organized:
Full disclosure, this is a simple contrived example to show the overall structure of a Blueprint.
Taking another step up the ladder to views, we have ERB and Jinja. This is where things get weird. One you might not be using them at all and instead be doing something returning JSON to a JavaScript application or mobile application; in other words, your views would not be part of your Python or Ruby code. The fact that Turbolinks is available for both languages both simplifies and complicates the comparison of the view layer. On the one hand, they are basically the same if you’re using Turbolinks. On the other hand, there are just so many ways to implement a front end these days that it seems impossible to actually have even a shallow comparison between the languages. Unfortunately, I am going to punt on this one, but I would ask that you follow up on Twitter with what you’re using from your front end.
There’s a lot more we could go into here, but this seems like a good place to call it for now. Again, there’s no winner and no loser. Both languages are great. If you want to learn more about Ruby technologies other than Rails and Rails itself, please take a listen to my podcast episode with the author of Rebuilding Rails, Noah Gibbs. My goal with this post is to start a conversation about these great languages and to explore how Ruby might grow, please me know what you think on Twitter. Also, if you need any Python or Ruby development work done, my software company, The Mad Botter INC is available.