My Impression of Ruby So Far

Posted on October 15, 2016 by Richard Goulter
Tags: programming.ruby, programming.scala, programming.haskell

Background

I’ve recently started programming in Ruby. I’ve inherited a codebase for writing automated-UI tests against a website. The tests make use of Capybara, which provides a high-level “DSL” for interacting with a webpage/browser in the sameway a user would; Capybara itself does this by abstracting over Selenium (or some other driver, like Poltergeist/PhantomJS); Selenium itself allows interaction with different web-browsers, by providing abstractions for different drivers of browsers (e.g. ChromeDriver).

As is also common for tests like these (called “UI tests”, “acceptance tests”, “functional tests”, “specifications”, “end to end tests” depending on who you ask) is use of Cucumber. – But that’s not too important for this post.

Very First Impression

Anyway,
I’d first read a few books before getting my hands dirty. (“Ruby Best Practices” and some of “The Ruby Way”). What I read was exciting enough: Ruby seems to be a language with decent pedigree, inheriting aspects from Lisp and the emphasis on message-passing from SmallTalk (as well as e.g. the power of Regular Expressions from Perl).
Also cool was e.g. Ruby’s dynamic features. Everything is an object, objects pass messages between each other. And so by overriding a few magic methods, some pretty cool things can be done. – e.g. the method_missing method is called if the object was called with a method that wasn’t defined on that object; so an object overriding this can have different behaviour.

That Ruby isn’t a low-pedigree language surprised me. ‘cause I kindof thought of Ruby as a “slightly prettier Python”. (It really isn’t, the philosophies of the two languages are quite different).
And while I’d heard Ruby documentation was ’good’, it was ‘good’ by-way-of “here’s an example of probably what you’ll want to do”.
And, well, if all someone knew was “Ruby on Rails”, then it’s kindof a good indicator that that person (prob’ly) doesn’t know how to program.

Steve Yegge also gave the language well-nuanced praise: that he didn’t like the language, but he found himself using it for everything when he had the choice; that he didn’t know the language, but he found he didn’t need to read the documentation while writing it (unlike other languages he was more familiar with).

Actually Using It

I’d say, Ruby isn’t as nice a blub language as Python is. To me it feels like a blub language, but with a message-passing system.

I guess I don’t like it as much coming from a Scala background:
“Ruby’s nice ’cause you can map/reduce over lists” … just like Scala. But without pattern matching.
And Ruby has nice “no brackets” syntax … like Scala. (Except in Ruby, it’s like o.m(x,y,z) can be o.m x, y, z; in Scala it’s more like x.op(y) can be written as x op y; in Haskell it’s f(x,y,z) must be written as f x y z). – Also, in Scala, operator overloading works for any symbol which is a valid method name, whereas Ruby takes C++’s approach.

That Ruby has symbols (like Lisp) is one thing I certainly do like about it, though.

And I guess I don’t like it as much coming from a Haskell background:
Say what you like about how shit Haskell documentation can be; (and I suppose outside “being too academic”, large-scale shit like Lenses can be god-damn atrocious to read). But at least it’s clear what types things have.
Ruby documentation makes clear what messages the objects receive. – The expectation is that the documentation give examples of different ways to use the method. Fucking good luck to you if the documentation lacks that. – This is slightly exasperated by Ruby’s “there’s more than one way to skin a monkey” philosophy, wherein a call to the same method-definition with different kinds of arguments ought to do the-right-thing.

And I guess it kind-of, sort-of makes sense for those familiar with Ruby, but I was surprised to learn that methods like map, etc. accept only procs; even if an objects method receives the same type of argument as an equivalent proc, the higher-order methods only take procs.
– The lack of tuples (in the same sense as Haskell or Scala or Python) also seems strange to me.

But the biggest woe I have with Ruby at the moment is “wtf errors”, presumably from the magic. – It’s not completely uncommon in statements calling Capybara (and therefore, Selenium, and ChromeDriver) to throw an "undefined method 'map' for 0:Fixnum (or nil:NilClass), when the statement contains no calls to map, nor any numbers/nil values. (I guess as a hint, the same statement may sometimes throw other errors about connection problems for some pipe).
– i.e. the call-stack from the exception doesn’t show the actual call-stack.
It’s possible, but very difficult, to debug this sort of thing. I still haven’t figured it out.

– All that said; this was on an non-idiomatic codebase I’d inherited. And I’m by no means yet comfortable with writing Ruby.

Conclusion / Hopes

So I find the syntax and semantics of Ruby conflict with what I’d expect, coming from a Scala/Haskell/Python background.
I’m not saying Ruby is a bad language. It looks like it’s pretty nice at writing message-passing paradigm programs. – But I don’t yet have love for the Ruby environment.


Btw, About Cucumber

Cucumber is a tool to help write “executable specifications”. The specification is written in e.g. Gherkin; the main aspect of a Gherkin specification is its sequence of Given/When/Then steps, written in a natural-language like English. – Cucumber tests will then bind these steps to code by matching the steps against a regex, and executing some code for that.
(In terms of “does the program pass tests”, this is kindof a costly abstraction to make, and for programmers-only, it’s easier to just write the executed code directly. – The purported benefit of writing executable specifications is more about communication: first that those involved in writing/reviewing the specification come up with an agreement of what the program ‘is’, & what terminology/phrases to use when discussing it; second that you get a (readable!) “living document” which describes what features the program has).

The automated testing suite is still quite young (currently working on getting it stable). I’m interested in seeing what difficulties come up in maintaining it (both from a technical and ‘social’ standpoint).


Newer post Older post