DEV Community

James Harton
James Harton

Posted on

Please stop using Ruby

I know what you're thinking but I want to start by saying that I love Ruby. Ruby is the language that made programming fun again for me after losing interest for a number of years. Ruby revitalised my career and allowed me to grow into the senior software engineer that I am today. Ruby is a lovely language. I just want you to stop using it.

For me Ruby came along in 2008 when I was working as a systems administrator at a local computer science department. I had written code in a bunch of languages before, and even enjoyed some of it but I was never able to feel completely productive or in tune with the language the way I felt when I started using Ruby. I was working with another team member to build a system to reimage lab computers using a combination of Rails, PXELINUX and BitTorrent. It was truly mad science. Also it worked really well - but that's a story for another day.

There was a bunch of reasons I stuck with Ruby after that first exposure and eventually transitioned into being a professional Rubyist. Below are the reasons I'm moving on and I think you should too.

Rails - the best tool for the job

If you wanted to make web applications in 2008 then Rails was simply the way to go. Sure there were other choices, but there were not other choices which were mainstream, had a reasonable talent pool available and were economic.

Rails drove the post-GFC startup economy. Not just because of the hipsters but also because it was the only framework at the time that allowed you to be so productive so quickly and to pivot your app easily when your hipster CEO decided to switch your dog food subscription website into an organic hemp running shoe e-commerce site.

Back then "the job" was a fairly constrained problem set: Take something from the database, squeeze it between brackets and serve it to the user. Then take some user input and stuff it back in the database.

These days the domain of a web app has expanded to include websockets, single page apps, APIs with their own query languages, web assembly and a bunch of tech that falls under the designation of "cloud". Web apps today look and behave completely differently to their 2008 counterparts - unless you look at a Rails app. Rails apps are still shuffling data back and forwards between databases and brackets - only these days there are more kinds of brackets.

Semantics - there can be only run

Ruby's DNA comes from a mixture of Perl and Smalltalk. Like Smalltalk Ruby features a dynamically typed classical object-oriented paradigm.

Ruby is a scripting language, meaning that the Ruby interpreter reads in source code, parses it and immediately starts evaluating it. There is no formal compile step. Runtime code defines (and redefines) constants, classes, methods and everything else. Runtime code can write more runtime code or modify or delete existing runtime code. In some cases the same class can have different behaviour depending on what lexical scope you're in. Ruby's semantics are so flexible that it was no wonder that Rails came along and told everyone their code had to fit into one of three folders.

When designing systems in Ruby you'll hear a lot about duck typing - the idea that you don't care what the type of an object is as long as it responds to the method you need. This is a way of having protocols without having to define them before hand, this makes sense because there is no "before hand", there's only runtime. In conventional cases it works quite well because most Ruby devs know that if you implement each then you can become an enumerable.

What this tends to mean in practice is that dynamic typing leads to subtle bugs because the wrong object is in the wrong place at the wrong time. The most common occurrence of this the infamous NoMethodError on NilClass. What this is saying is that you tried to call a method that doesn't exist on nil but what it really means is that somewhere below you in the stack a method returned nil instead of the thing you were expecting. It doesn't tell you where your bug is, just where the effects of it were finally intolerable to the system.

Because Ruby's semantics defy almost any kind of static analysis where a user of another language could add a type constraint or at least pattern match to avoid this situation the Ruby programmer is left with only one option: write a truly heroic number of unit tests in an effort to formalise what data is allowed to flow in and out of methods and objects and that it doesn't explode when the wrong input is given.

One other side effect of duck typing is the common use if backhanded type checking in the form of object && object.method to verify that the collaborating object is at least truthy before calling a method on it. This is so common that Ruby 2.3 added the &. safe navigation operator to turn this design problem into a virtue.

Performance - there can be only one

Let's get this out there first of all. Ruby is slow. Conventional wisdom is that Ruby is "fast enough" and that you can always throw more hardware at a problem. This is true to a certain extent, but most machines are multi-core these days and...

I don't consider myself as the threading guy, so I don't think I can make the right decision about the Actor library or the threading library.
Matz - creator of Ruby

...Ruby is also no good at concurrency. MRI has a global interpreter lock, which means that only one YARV instruction can be run at a time. There's a bunch of places where this can be worked around - like sleeping threads waiting for IO but fundamentally, if you want to do more than one thing at a time you need to run multiple interpreter processes.

Lastly, Ruby tends to use a lot of memory and it doesn't like giving it back to the operating system. There are ways to mitigate these problems to a certain extent, but most Rubyists are not aware of them or are simply used to the situation.

A lot of work has been put in by the Ruby core team over the last few years and I'll be the first to admit that Ruby 2.5 is much much faster than it used to be. Many would argue that it's fast enough. I would not.

Resilience - exceptional situations

As described above, even when running with multiple threads Ruby essentially runs a single interpreter with no built-in fault tolerance primitives so unhandled exceptions will take down the entire VM. There have been legendary efforts by the community at writing actor systems but ultimately those teams have given up and moved to languages who give them the tools they need to build reliability into their products (example Celluloid).

Tooling - from 0X to DX

The Ruby (and especially Rails) community lead the way in terms of good tooling to help developers achieve results quickly. Tools like Rake, Bundler, RSpec and the Rails command line really did blaze a trail for developer experience, however other languages have caught up and even overtaken Ruby in their tooling game. Rust's cargo, Elixir's mix and Scala's sbt all combine these tools into a single command and go the extra step of tightly integrating them directly into the language. And it's not just languages that have upped their tool game but also client side frameworks, DevOps systems and cloud providers.

Packages - to infinity and beyond

Ruby is blessed with a very large number of packages (or gems) which provide pretty much any kind of functionality you can think of. Not quite as many as that other language but I'd argue that on average they are of a much higher quality. Need an out-of-the-box authentication system? There's a gem for that. Need a massively overblown and architecturally questionable state machine that is weirdly tied to your database? There's a gem for that too.

Before Rubygems there really was only CPAN but no one needs to be reminded of that. Ruby's model of easily consumable and integrated packages paved the way and has been adopted by many many other languages, eg: crates, hex, CocoaPods and elm/packages.

So what should I use Ruby for in 2018?

For me, irb is still my go to tool to quickly work something out and I'll still write little Ruby scripts to orchestrate little one-off jobs like moving files around or sucking down an API responses.

When we talk about Ruby it's hard to ignore Rails, so I guess the question is "what should I use Rails for in 2018"? If you have an app that meets the following criteria then I expect that Rails will still be a good match for you:

  • is almost entirely database driven,
  • renders pages on the server or generates JSON,
  • can be mostly assembled out of existing gems,
  • doesn't have complicated business logic,
  • doesn't need to be fast,
  • doesn't need to serve many people at once,
  • won't ever change.

I'd still argue that you have better options though.

Top comments (72)

Collapse
 
thecodetrane profile image
Michael Cain

So...respectfully, I am going to go in on this.

I really feel like we need to slow our roll on shit-talking Ruby on Rails. Very few of us are ever going to have to worry about scale on a level where Ruby‘s raw performance metrics are going to be that impactful. Plus, let us not forget one of the main tenets of Ruby: programmer happiness.

I did not go to school for CS, so I don’t have the acquired taste for FP that a lot of folks have, I guess. I’m a digital carpenter; I want the code to be clear, easy to understand and flexible. Ruby is one of the best for that.

If you really think that you’re going to be managing 1M connections on one node a la Elixir (WhatsApp), go for it. That said, let’s keep the click-baity holier-than-thou hot takes to a minimum.

Collapse
 
sam_ferree profile image
Sam Ferree

You don't think there's anything holier-than-thou about idea that Ruby is one of the happiest languages to code in? Is the hardly subtle implication that engineers who care about performance can't possibly care about readability really going in on this respectfully?

What are the metrics for programmer happiness? How did you collect your data? What's your sample size? How can you even begin to honestly substantiate that claim beyond "I like it and everyone who insists on using it despite it's demonstrable problems likes it."

Everyone who insists on writing C# likes it, and people who insist on writing Elm are convinced that functional programming is obviously the most pleasant. Some people still swear by Ada.

Ruby is one language of many that allows you to write readable code.

And while there are languages that make it hard to write readable code; there are zero languages that make it hard to write unreadable code. Ruby doesn't even make writing unreadable code the least bit difficult.

I once was stuck on a rails error for 2 hours because I typed validate instead of validates. Any compiled language's editor would have caught that as soon as I typed it. Ruby was able to spin up the whole app and run indefinitely without ever feeling the need to say "BTW, I don't know what that method is."

Is "Please Stop using Ruby" a click-bait headline? For sure.
Are some of his criticisms of the language valid? Absolutely.
So yeah, this should have definitely been titled something like "Considerations to take into account before starting your next web project as Ruby on Rails"

Collapse
 
thecodetrane profile image
Michael Cain

I never said "Ruby is one of the happiest languages to code in". I said it's primary focus is "developer happiness', which is direct from Matz.

I think the fact that RoR is the de facto on-ramp for most devs coming out of boot camps says a lot for its accessibility. Is Ruby the happiest language? Highly unlikely! People are made happy for all sorts of reasons.

My whole point was addressing the obviously craven title and the nasty habit people have for shitting on other peoples' tools. Write your next app in mindf*ck for all I care. If that's what makes you happy and it does the job, great! The idea, however, well all need these super-concurrent, ultra-fast, functionally-programmed, EVERYTHING-less apps is silly. Very little of what most of us do is a) that serious and b) even going to be around in 5 years.

Thread Thread
 
sam_ferree profile image
Sam Ferree

You’re absolutely right that shitting on people’s tools is bad.

I don’t know that i’m aware of sufficient evidence to agree that “what most of us do is [not serious enough for the performance concerns to matter].” And the claim that what most of us are doing isn’t going to be around in 5 years disagrees with my experience. Anecdotal I know, but a company a worked for until recently still maintains and adds new features to and ASP classic application.

Thread Thread
 
thecodetrane profile image
Michael Cain

I certainly agree that languages/frameworks persist. I work on a team as the only RoR guy with a bunch of Java developers. We have services in C# all over the place. All the more reason to cease and desist with the "mine is bigger than yours" malarkey.

Collapse
 
mhenrixon profile image
Mikael Henriksson

validate is also a claim method in rails. Your example does not prove your point at all. It just shows you don't know rails well enough. Sorry, couldn't let someone be wrong on the internet. 😂

Thread Thread
 
sam_ferree profile image
Sam Ferree

"I don't know rails well enough" exactly proves my point when the opposing point is "rails is a productive framework and makes developers happy!"

Collapse
 
shalvah profile image
Shalvah

Just here to say that I love your "digital carpenter" phrase! Adopting it ASAP! 😆😆

Collapse
 
ondrazizka profile image
Ondrej Zizka • Edited

IDK man. I am in like 7th company in my life, ranging from 10k employees to the current startup of 100, and in all of them, the apps deal with thousands of parallel connections. And it is big difference if your hourly batch takes 15 minutes on JVM or 3 hours on Ruby, because then you need to write your app as parallel right away (something not easy to do in Ruby) and them run it on 3 nodes, just because someone liked Ruby.

Your metrics for happines, clear code, easy to understand and flexible are subjective; personally, with Ruby, I was unhappy, the code was mostly messy, hard to undestand, ad very rigid.

Collapse
 
89885512495 profile image
Sony

sry...but do you think that this code is easy to understand:

vowelsCount = Hash['aeiou'.chars.map{|n| [ n, 0 ]}]
gets.chomp.chars.each{|n| vowelsCount[n] += 1 if vowelsCount.key?(n)}

I am doubt.

Collapse
 
thecodetrane profile image
Michael Cain

You can write unintelligible nonsense in any language, my dude. Ruby's focus is "developer happiness", and I feel that it delivers. If you prefer to make yourself miserable, Java will welcome you with open arms.

Collapse
 
jerodsanto profile image
Jerod Santo

Please stop using absolutes in article titles. It's condescending and only serves to annoy, infuriate, or (worst of all) repel your prospective reader. 💚

Collapse
 
fareedjaved profile image
Fareed Javed • Edited

It's strange to see someone who benefited so much in their career from using Ruby and RoR turn around and discourage others from using it as well. The reasons you list to not use Ruby lack nuance. For example, you claim Ruby is slow, but what are you comparing it to and in what situation? Yeah, Ruby doesn't take advantage of multiple cores, but that doesn't mean it's useless.
And the reasons you list why someone should use Rails are incredibly backhanded. Saying someone should use Rails if their app never changes or if it doesn't have complicated logic is not apart of a #healthydebate.

And just because a language is faster and compiled that does not guarantee that you will write better software.

The point of rails is that it lets you develop and iterate over a prototype very quickly. This is the reason a lot of successful companies were able to get off the ground and make money relatively fast.
Also, those same companies have used Ruby for very complex systems. An example is Airbnb, who wrote their large scale payment application initially in Rails. While they did migrate to Apache Kafka & Spark, they did it because of the massive increase in users, not because Ruby isn't multi-threaded.

Ruby and RoR were never meant to be the perfect tools but only focusing on their drawbacks isn't enough for telling people to stop using the language. And it's frustrating to see this kind of thinking in 2018.

Collapse
 
skatkov profile image
Stanislav(Stas) Katkov

I can relate to your experience, James. I tried moving to other frameworks, even to better option you mentioned.

But rails has one big upside, which is hard to ignore -- maturity of libraries (gems). With a big probability I can find a library that satisfies my picky requirements.

With Phoenix and Elixir I still find myself spending too much time on very trivial things. Since I'm an indie dev -- this is a luxury I can't afford.

But I can afford rewriting some components in languages that performs better, if there is a bottleneck in Ruby itself. But in a lot of cases, I just know how to make Ruby performant :)

Collapse
 
richjdsmith profile image
Rich Smith

Yep, as a one-man-show, it's tough to argue there are a lot of better options that allow for more productivity/hour than RoR.

If I find myself in a situation working on something that has 1mm connections simultaneously, sure, I'll use Elixir. But to spin up a CRUD app, which honestly, are still to this day, most online web apps, Rails and Ruby are tough to beat.

Collapse
 
shevegen profile image
markus heiler

I use my own fake-webframework (created before rails came out).

Granted, it is way below feature parity with rails. But it also does not want to be feature equal.

I also use sinatra so I more belong into this world of simplicity.

And I am mega-productive related to the www there too, without needing RoR (but I value simplicity at all times; I hate the complexity of rails).

I just wonder why people think the www in ruby belongs to rails. I don't see it that way at all.

Thread Thread
 
princejoseph profile image
Prince Joseph

what is your framework?

Collapse
 
jimsy profile image
James Harton

I agree that Rubygems is one of the main reasons that people stick with Ruby and it is an amazing resource. I've written my fair share of gems over the years and I hope that they helped people in some way. Working with Phoenix can be pretty annoying when you can just get a hex package that just handles user authentication the way that devise does - you have to wire up a lot of code to get it to work. I think this is mostly about maturity but I think it will get there. I once joked that Elixir is powered by thousands of angry Rubyists and like all jokes I think there's more than a grain of truth in it.

Collapse
 
shevegen profile image
markus heiler

Rubygems is great but I do not rely on it.

I can write whatever I need just fine, if I need it.

I wrote my own "package" manager in ruby and have been using that for ~13 years to manage my *nix systems.

I once joked that Elixir is powered by thousands of angry Rubyists

Elixir has great ideas; erlang is awesome, but the syntax of erlang is UTTER SHIT.

But even then, too few people use elixir; and even fewer use crystal.

Say what you want about ruby but ruby IS used by LOTS of people.

I think this is mostly about maturity but I think it will get there.

This depends on how many people use a language. Crystal struggles a lot because of this - too few people go into crystal. Which is a shame. But I myself also am not using crystal, primarily due to lack of time; but also because the type-madness leads to syntactic monsters that I don't want to deal with.

Note that ruby 3.0 will get additional type information, so some of your fake-complaints above may be answered.

I still think your article is horrible though. Please try to make your points more objective in general.

Collapse
 
betogrun profile image
Alberto Rocha

The #healthydebate hashtag and this clickbait title doesn't match.

Collapse
 
rhymes profile image
rhymes • Edited

A few points:

  • Rails is adapting to this world that just doesn't ony "shuffle data back and forth" (integrating webpack, adding websocket support). Also stimulus.js by Basecamp goes into that direction

  • Ruby is getting better and better (well it would be funny if it got worse :D): there's talk of adding JIT compilation, guilds (sort of isolated processes in user space) and type decoration

Maybe it won't innovate fast enough and lose developers (it happens to every technology I guess) but there's a valid argument for it you didn't make: there are still tons of Rails jobs :-)

Rails (and Django) are turning into "boring technologies", which is not inherently bad :-)

I'm more optimistic about their future.

Collapse
 
ben profile image
Ben Halpern

My sense of parcel anxiety from yesterday is eased big time from leadership in the Rails community which does a great job of sniffing bullshit in web development and keeping things smooth.

This probably keeps me in Ruby more than anything else.

Although Rust and Elixir and others have a lot of former Rubyists leading the way in DX and pragmatism, as the post implies. Still, Rails makes me feel like I have some serious teammates in the game from small-to-medium-to-big organizations and lots in between. It's such a rock solid boring ecosystem.

Collapse
 
jimsy profile image
James Harton

This is really great to hear and I am forced to admit that I stopped following along with changes to Ruby a few years ago.

I also agree that "boring" is exactly what you want in production. But boring and slow?

Collapse
 
rhymes profile image
rhymes

"Fast enough". This is a really good article from an expert in Ruby and Rails: Is Ruby Too Slow For Web-Scale?

Collapse
 
spidergears profile image
Deepak Singh

No, I won't. I would only agree that Ruby is not the go to language for everything you do or for everyone / every project.

That being, please weigh your choices with care, use matrices that make sense and avoid noisy opinions you see on web.

Collapse
 
yoelblum profile image
Yoel • Edited

So it's basically a long and click baity article about static types > dynamic types? Wow never heard that argument before. Oh yeah and the performance issue, of course. Happens to me everyday at work when I need to sprinkle more performance on my app but alas Ruby fails yet again. If only it was written in java.

Collapse
 
stereobooster profile image
stereobooster

Because Ruby's semantics defy almost any kind of static analysis where a user of another language could add a type constraint

I will leave it here:

Collapse
 
thorstenhirsch profile image
Thorsten Hirsch

Looks like Javascript+Flow to me, which is by far not as capable as Typescript. I love Ruby, but typing is a language feature and does not belong into a library. IMHO. Hope Ruby 3.x will come with optional typing.

Collapse
 
stereobooster profile image
stereobooster

This will not happen. I saw a quote from Matz that he believes that type signature will be obsolete in 10 years and he doesn't want to add them (I will need time to find it). Important: he didn't say that he against static types (he is for it), he didn't say he against static analysis (he is for it).

The second point, nobody wants to repeat the Python2 vs Python3 situation, so it will be a gradual type system (I guess).

Javascript+Flow to me, which is by far not as capable as Typescript

I'm doing a series of blog posts on Flow and TypeScript. There are, for sure, differences, but not so dramatic. The biggest issue with Flow is closed development, awful tooling and not very big community, but not the power of the type system itself. It is fairly comparable to TypeScript.

Collapse
 
azeemh profile image
azeemh • Edited

No. I will continue to use Ruby and whatever languages best addresses my use case. Fuck off with your stupid titles. Please stop writing shitty articles. Thanks. Fyi rails supports websockets and actioncable. And ops uses vms so just run a bunch of vms on multicore machines if you need concurrency and configure the appropriate port forwarding to apache nginx. Finally Airbnb and Shopify as well as Github are made with ruby and they make $$$. 1 man can do a lot with rails.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.