davideisinger.com

My personal website
Log | Files | Refs | README

index.md (8087B)


      1 ---
      2 title: "Why I Still Like Ruby (and a Few Things I Don’t Like)"
      3 date: 2020-08-06T00:00:00+00:00
      4 draft: false
      5 canonical_url: https://www.viget.com/articles/why-i-still-like-ruby-and-a-few-things-i-dont-like/
      6 featured: true
      7 references:
      8 - title: "The History of Ruby — SitePoint"
      9   url: https://www.sitepoint.com/history-ruby/
     10   date: 2023-11-16T14:54:03Z
     11   file: www-sitepoint-com-6vwmef.txt
     12 - title: "In Ruby, Everything is Evaluated - Mufid's Code blog"
     13   url: https://mufid.github.io/blog/2016/ruby-class-evaluation/
     14   date: 2024-01-31T15:55:28Z
     15   file: mufid-github-io-2czqvc.txt
     16 - title: "Decorating Ruby - Part Two - Method Added Decoration - DEV Community"
     17   url: https://dev.to/baweaver/decorating-ruby-part-two-method-added-decoration-48mj
     18   date: 2024-01-31T15:55:49Z
     19   file: dev-to-pywrcp.txt
     20 - title: "JavaScript Needs Blocks"
     21   url: https://yehudakatz.com/2012/01/10/javascript-needs-blocks/
     22   date: 2024-01-31T15:55:29Z
     23   file: yehudakatz-com-sacizu.txt
     24 - title: "When Should You NOT Use Rails?"
     25   url: https://codefol.io/posts/when-should-you-not-use-rails/
     26   date: 2023-11-04T17:36:55Z
     27   file: codefol-io-bskabg.txt
     28 ---
     29 
     30 The Stack Overflow [2020 Developer
     31 Survey](https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-languages-loved)
     32 came out a couple months back, and while I don't put a ton of stock in
     33 surveys like this, I was surprised to see Ruby seem to fare so poorly --
     34 most notably its rank on the "most dreaded" list. Again, who cares
     35 right, but it did make me take a step back and try to take an honest
     36 assessment of Ruby's pros and cons, as someone who's been using Ruby
     37 professionally for 13 years but loves playing around with other
     38 languages and paradigms. First off, some things I really like.
     39 
     40 ### It's a great scripting language
     41 
     42 Matz's original goal in creating Ruby was to build a truly
     43 object-oriented scripting language[^1], and that's my
     44 favorite use of the language: simple, reusable programs that automate
     45 repetitive tasks. It has fantastic regex and unix support (check out
     46 [`Open3`](https://docs.ruby-lang.org/en/2.0.0/Open3.html) as an
     47 example). I might not always build Ruby apps, but I'll probably always
     48 reach for it for scripting and glue code.
     49 
     50 ### A class is a little program
     51 
     52 This one took me awhile to get my head around, and I'm not sure I'll do
     53 a perfect job explaining it, but when a Ruby class gets loaded, it's
     54 evaluated as a series of expressions from top-to-bottom, like a normal
     55 program. This means you can, for example, define a class method and then
     56 turn around and call it in the class' top-level source; in fact, this is
     57 how things like `has_many` in Rails works -- you're just calling a class
     58 method defined in the parent class. In other languages, you'd have to
     59 reach for something like macros to accomplish this same functionality.
     60 
     61 [Here's an alternate
     62 explanation](https://mufid.github.io/blog/2016/ruby-class-evaluation/)
     63 of what I'm getting at and [here's a cool
     64 post](https://dev.to/baweaver/decorating-ruby-part-two-method-added-decoration-48mj)
     65 that illustrates what sort of power this unlocks.
     66 
     67 ### The community is open source-focused
     68 
     69 Ruby has a rich ecosystem of third-party code that Viget both benefits
     70 from and contributes to, and with a few notable
     71 exceptions[^2], it's all made available without the
     72 expectation of direct profit. This means that you can pull a library
     73 into your codebase and not have to worry about the funding status of the
     74 company that built it (contrast with ventured-funded open-source like
     75 [Gatsby](https://www.gatsbyjs.org/) and [Strapi](https://strapi.io/)).
     76 Granted, with time, money, and a dedicated staff, the potential is there
     77 to build better open source products than what small teams can do in
     78 their free time, but in my experience, open source development and the
     79 profit motive tend not to mix well.
     80 
     81 ### Bundler is good
     82 
     83 It's simple, universal, and works well, and it makes it tough to get
     84 into other languages that haven't figured this stuff out.
     85 
     86 ### It has a nice aesthetic
     87 
     88 It's easy to make code that looks good (at least to my eye) and is easy
     89 to understand. There's less temptation to spend a lot of time polishing
     90 code the way I've experienced with some functional languages.
     91 
     92 ## And some things I don't like as much
     93 
     94 Lest ye think I'm some diehard Ruby fan, I've got some gripes, as well.
     95 
     96 ### It's not universal
     97 
     98 As I said, my favorite use of Ruby is as a scripting language, so it's
     99 unfortunate that it doesn't come installed by default on most unix-y
    100 systems, unlike Perl, Python, and Bash. If you want to share some Ruby
    101 code with someone who isn't already a Ruby dev, you have to talk about,
    102 like, asdf, rbenv, or Docker first.
    103 
    104 ### Functions aren't really first-class
    105 
    106 You can write code in an FP style in Ruby, but there's a difference
    107 between that and what you get in a truly functional language. I guess
    108 the biggest difference is that a method and a lambda/block (I know
    109 they're [a little
    110 different](https://yehudakatz.com/2012/01/10/javascript-needs-blocks/)
    111 don't @ me) are distinct things, and the block/yield syntax, while nice,
    112 isn't as nice as just passing functions around. I wish I could just do:
    113 
    114 ```ruby
    115 square = -> (x) { x * x }
    116 [1, 2, 3].map(square)
    117 ```
    118 
    119 Or even!
    120 
    121 ```ruby
    122 [1, 2, 3].map(@object.square)
    123 ```
    124 
    125 (Where `@object.square` gives me the handle to a function that then gets
    126 passed each item in the array. I recognize this is incompatible with
    127 optional parentheses but let me dream.)
    128 
    129 ### It is probably too flexible
    130 
    131 Just like skiing, the most dangerous time to be a Ruby developer is the
    132 "early intermediate" phase -- you've learned the syntax and language
    133 features, and all of a sudden EVERYTHING is possible. Want to craft the
    134 perfect DSL? Do it. Want to redefine what `+` does for your Integer
    135 subclass? Do it. Want to open up a third-party library and inject a
    136 custom header? You get my point.
    137 
    138 As I've said, Ruby makes it easy to write nice-looking code, but it
    139 takes restraint (and mistakes) to write maintainable code. I suppose the
    140 same could be said about the programming discipline in general, but I
    141 can see the appeal of simpler languages like Go.
    142 
    143 ### Type checking is cool and Ruby doesn't have it
    144 
    145 The first languages I learned were C++ and Java, which formed my
    146 opinions of explicit typing and compilation and made Ruby such a
    147 revelation, but a lot has changed in the subsequent decade, and modern
    148 typed languages are awesome. It'd be neat to be able to compile a
    149 project and have some level of confidence about its correctness before
    150 running the test suite. That said, I sure do appreciate the readability
    151 of things like [RSpec](https://rspec.info/) that rely on the
    152 dynamic/message-passing nature of Ruby. Hard to imagine writing
    153 something as nice as this in, like, Haskell:
    154 
    155 ```ruby
    156 it { is_expected.not_to allow_values("Landlord", "Tenant").for(:client_type) }
    157 ```
    158 
    159 (As I was putting this post together, I became aware of a lot of
    160 movement in the "typed Ruby" space, so we'll see where that goes. Check
    161 out
    162 [RBS](https://developer.squareup.com/blog/the-state-of-ruby-3-typing/)
    163 and [Sorbet](https://sorbet.org/) for more info.)
    164 
    165 ------------------------------------------------------------------------
    166 
    167 So those are my thoughts. In the end, it's probably best to know several
    168 languages well in order to really be able to understand
    169 strengths/weaknesses and pick the appropriate one for the task at hand.
    170 If you're interested in other thoughts along these lines, you could
    171 check out [this Reddit
    172 thread](https://www.reddit.com/r/ruby/comments/hpta1o/i_am_tired_of_hearing_that_ruby_is_fine/)
    173 (and [this
    174 comment](https://www.reddit.com/r/ruby/comments/hpta1o/i_am_tired_of_hearing_that_ruby_is_fine/fxvfzgo/)
    175 in particular) or [this blog
    176 post](https://codefol.io/posts/when-should-you-not-use-rails/), but what
    177 really matters is whether or not Ruby is suitable for your needs and
    178 tastes, not what bloggers/commenters/survey-takers think.
    179 
    180 [^1]: [*The History of Ruby*](https://www.sitepoint.com/history-ruby/)
    181 [^2]: I.e. [Phusion Passenger](https://www.phusionpassenger.com/)