Crossing the Rubycon
I first learned Ruby about a year ago and it quickly became my scripting language of choice; a position I doubt it will ever lose, hence the name of this blog post. Here are some of the reasons that I prefer Ruby over Python, NodeJS, and PHP, for most use cases.
Testing
The primary reason I prefer Ruby is how great writing tests is. Tests in ruby can be incredibly concise and natural. The built in mocking, stubbing, and monkey-patching functionality is very powerful. I particularly love the way contexts can be built up with let(:...) to have very descriptive and concise tests.
The philosophy
If you look at a language like PHP, it has basically no philosophy behind it, at least not a consistent one. Hence you end up with all sorts of weird behaviors. For example, consider preg_match, which finds matches of a Regex in a string:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or false on failure.
Gross. Wait, where are the results of the regex match?
// get last two segments of host name
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "domain name is: {$matches[0]}\n";
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "domain name is: {$matches[0]}\n";
They're passed in by reference? I have no words. This is what happens when you have a scripting language that was originally meant to be a template language for web apps written in C.
Ruby is the opposite. Ruby was built around the philosophy of being a natural programming language to use, and that really shows. It's by far the most natural programming language I've ever used. I was able to pick up Ruby and guess most function names without having to look through documentation. In Ruby, what you would expect to work usually works.
Ruby on Rails
Certainly one of the best parts of Ruby is its most popular web application framework: Ruby on Rails. Rails is the only framework I've ever used with a truly consistent philosophy. In particular, I love the "Provide Sharp Knives" doctrine, which is reflective of Ruby in general. You can really hurt yourself with a sharp knife, but if you know how to use one, it's highly effective. The Rails doctrine sums up most people's baseless fear of sharp knives:
Because it’s always about other programmers when the value of sharp knives is contested. I’ve yet to hear a single programmer put up their hand and say “I can’t trust myself with this power, please take it away from me!”. It’s always “I think other programmers would abuse this”. That line of paternalism has never appealed to me.
If you can't trust your colleagues with sharp knives, you may need to find a better place to work. The other thing I love about Rails is that it's essentially a standard in the Ruby community. I'm not aware of any framework that consumes such a large market share of its language's users. This market dominance has many benefits, including the fact that Rails has incredible community support.
What are the downsides?
With great power comes great responsibility. Ruby gives programmers incomparable power to change the language as they see fit. This is a double-edged sword which can have catastrophic effects if you're not careful. The biggest challenge I've come across so far has been navigating all of the magic that comes with the Rails framework.
ActiveRecord stands out as particularly easy to abuse. The simplicity of using inter-model relations can make untangling complex webs of model dependencies very difficult. It becomes too easy to cluster together unrelated fields and dependencies. Worse yet, it is common to see ActiveRecord models containing business logic. If you're trying to move from a Rails monolith to microservices, these common practices complicate matters significantly.
The best advice I have is to use Domain Driven Design to ensure that business concerns are separated from framework concerns. More generally, business logic should be separated from persistence, and presentation logic should be separated from both. Rails makes it too easy to mix all of these together, and the responsibility of creating a maintainable system falls entirely on the programmer. After all, trusting the programmer to do the right thing is a major part of the Ruby philosophy.
Comments
Post a Comment