Frustrating and Cryptic Ruby Idioms (#1 of a series)

I keep coming across these FACRI's (Frustrating and Cryptic Ruby Idioms) in my work, so I'm jotting them here in the hope that I'll remember them better in future.

Ruby idioms

Ruby is a wonderful, if somewhat slow and memory hungry language, with an incredibly flexible and expressive syntax. However this flexibility leads to the creation of idioms that initially look totally opaque, if you don't know what to look for.

Case in point: the object{:&method} idiom

If you want to take an array called names , want to create a new array by running a text manipulation on every member of that array, a terse, but readable way to do this would be:

result = names.map { |name| name.upcase }

The intent is pretty clear here, and what happens programatically is also very readable. Another way to do this though is write it like:

result = names.map {&:upcase}

Something called type coercion is occurring here; you normally pass the map method a Proc object to execute, with a placeholder name for each iteration, and the code to run and return. However because you're not passing a Proc object here, Ruby tries to convert it on the fly into a Proc object using a method called to_proc:

def to_proc proc { |obj, *args| obj.send(self, *args) } end

So in this case, it's passing in names, and the method in the *args is upcase. I wasn't familiar with the send method here either, so the documentation for it from ruby core may help here:

class Klass def hello(*args) "Hello " + args.join(' ') end end k = Klass.new k.send :hello, "gentle", "readers" #=> "Hello gentle readers"

An expensive idiom, by rockstars, for rockstars.

Th end result of all these examples is a saving of about 12 characters, at the expense of readability, and a huge performance hit as each member in names of passed around and type coerced like there's no tomorrow.

If you're a coding savant, the elegance of this will probably make you weep tears of syntactic joy, and the clever brevity of this isn't lost on me.

However, coming to this, without too much knowledge of the Ruby extensions project, or someone to talk you through what's happening is likely to be a frustrating experience.

Hope fully this will save time for someone else in future.



Copyright © 2020 Chris Adams
Powered by Cryogen
Theme by KingMob