Here at NextLink Labs, we often find ourselves in spirited debates and discussions about various programming languages and frameworks. Recently, I was having one of these debates with one of our engineers who loves Ruby and thinks Ruby on Rails is the best web framework to grace cyberspace. I love Python and prefer Django -  even if I will admit that Rails has definitely been more influential. 
Anyway, we were discussing the finer points and niceties of each, when I realized these would be interesting topics to explore in a technical blog post.

You can see the follow-up blog post for Python, as well as for Ruby on Rails vs. Django here [links]. 

So let's get down to business.

History

Ruby was created in 1995 by a Japanese computer scientist Yukihiro Matsumoto, usually referred to as Matz. Apparently, the name Ruby was named after a colleague’s birthstone. I will always have a fondness for Ruby as it was the language that I originally learned to program in.

Here is what the official Ruby website has to say: 

"Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. Matz's approach to designing Ruby to be as intuitive as possible has resulted in a language that, while powerful, also enables rapid application development."

They definitely have a strong adjective game. Here are Ruby's most notable characteristics:

Strongly Object Oriented

The first thing that comes to mind is that Ruby is very strongly object oriented as opposed to Python. This is by design. In fact, when Matz created Ruby, he already knew Python but wasn't happy with it. 

As he states, “I knew Python then. But I didn't like it, because I didn't think it was a true object-oriented language – OO features appeared to be add-ons to the language.”
In Ruby, everything is both mutable and an object. This means that each type of information (like numbers, true/false values, strings, etc.) can have their own behaviors and be passed around between classes or modules easily. This also means inheritance is a big part of programming with Ruby as all objects can easily gain the methods and behaviors of others. Generally, this is more intuitive for people than a chain of functions.

Of course, everything in life comes with trade-offs; Ruby's strict adherence to OOP also causes several issues. First, treating everything as an object, even the smallest minutiae or most abstract concept, requires more overhead and is more memory intensive than most other languages. Furthermore, designing an effective OOP system in Ruby requires thoughtful design and forethought. Drastically changing classes halfway through a project is time consuming and can be overkill for smaller projects.

Open Source and Gems

The other major defining feature is that Ruby is an open-source programming language. This means all of its code is public knowledge. This allows the community to also actively contribute to its development by creating libraries (“gems”)  that provide additional functionalities or even full-on web frameworks like Ruby on Rails.

He democratic nature of being open source means the quality of these gems can vary drastically. Indeed, if a gem is no longer maintained or updated, it may break or become a security risk, potentially leading to significant problems in the projects that depend on it. It also can lead to dependency hell when multiple gems with various versioning rely on other gems with various versioning. If you program long enough, you will definitely run into these two issues.

Even so, I would say the gem system for Ruby is usually very good as it offers a standard format for distributing Ruby programs and libraries, and the single gem file makes package management straightforward.

Flexibility

Further, nothing is sacred in Ruby; essential parts of Ruby can be removed or redefined and existing parts added upon. If you want to change the basic String class to always return False, you can do that. If you want Structs to make you a cocktail, well give AI and robotics a decade or so and that can happen. 
Unlike a strongly typed language like Java, Ruby developers don't need to do cumbersome things like tell functions what type of arguments they can accept. These traits, combined with dynamic typing makes Ruby an extremely flexible language.

Flexibility is great, especially when working on your own projects. Flexibility also means that there are no guard rails: Ruby's malleability can be misused by the overly clever or careless. Working in larger teams, this can become a problem as changing fundamental parts of the language can make codebases unpredictable, harder to read and expand, and debugging more difficult.

Interestingly, this flexibility of the language can lead to tension with the next principle of Ruby.

Principle of Least Surprise

One of the more notable features of Ruby is its use of the principle of least surprise (POLS), a software design principle introduced by Matz. The idea is pretty simple: a programming language should behave in such a way that minimizes the user's surprise. This principle of least surprise led to a consistent design pattern: Ruby is made to be intuitive over other considerations (such as performance). This makes it easier to learn than other programming languages (C++ for instance). Ruby is the dependable head of the family and the salt of the programming Earth. You can contrast this to JavaScript for instance, which I think of more like the erratic cousin at the family reunion that forgot to take their meds.

Of course, POLS is somewhat subjective: what is unsurprising to some might come as a shock to others. I don't think that this is a problem unique to programming of course.

Nonetheless, this focus on being simple and intuitive comes at a price.

Simplicity and Complexity

On the surface, the Japanese Ruby aims to have a simple English-like syntax. I find this sort of ironic: ask any non-native English speaker if English, the language with by far the most words and idioms, is simple. Still, given that the origins of the internet are American, most major tech companies are American, and the world-wide web was invented by a British scientist, English for better or worse is the de facto language of tech. But I digress. 

Achieving this simplicity programmatically isn't easy however as English is not logically consistent or complete. To achieve this goal, Ruby hides complex behaviors or details from the developer under the hood. The main way this is accomplished is via metaprogramming, which is the ability for code to manipulate itself and other code. This means that in terms of performance, Ruby generally executes slower than languages like C++ or Java. Further, metaprogramming can make it harder to understand what the language is actually doing, and can lead to unexpected results when dealing with more advanced or complex tasks. 
Surprising, huh? 

Concluding Thoughts

Ruby. Both simple and not simple. Because its syntax is so readable and the language is so flexible, Ruby is a good language to learn programming (like I myself did). For very large projects however, the performance issues, memory consumption, and metaprogramming obfuscations can be an issue that should be considered. 

Overall, I would say that Ruby has a strong flavor. Umami, perhaps?