A Ruby-ish Xmas

Ruby-ish, rubbish… Get it? Anyways, not like Ruby-ish means bad! Quite the opposite!

It’s the day after Xmas and because Ruby is awesome and delivered 2.6.0, we’ll get to play with some of our new Xmas gifts: Kernel#then, Proc#>> and Proc#<<.


This is a very Ruby-specific post, but hopefully everyone can get something out of this.

Let’s start with #then, which is actually just an alias to an already-existing method: #yield_self. But #then is much prettier, don’t you agree?

Let me show you why this is cool.

Playing with… function composition?

Calling functions and composing them is common among most modern programming languages, be it in the form of methods, functions, lambdas, closures, blocks, procs, or whatever the language calls it.

A function is basically a calculation associated with a name. It takes some input, and returns some output.

In most programming languages, the standard way to call a function is the same as you’d do in math: sum(2) calls the function sum with the argument 2.

This works most of the time, but when you need to call several functions, it can get messy.

When using the regular f(g(x)) syntax, the first operation performed — g(x) in this example — is hidden inside a “wrapper” function. The more wrappers we have, the harder the expression is to understand.

In the pseudo-code below, assume people is just a list of people.

Which operation is the first there? It’s not immediately clear. We see count first, then nameStartsWith and then olderThan. But the order in which they get called is actually the reverse. So it’s hard to know what this whole thing
does.

NOTE: This is a good example of good naming conventions — the variable is called mikes_older_than_18.

What the functional language designers added is a new way to call functions: Instead of saying g(x), you can say x | g. That means “send the left side as first argument to the right side”.

That might seem arbitrary, and even useless, but consider this: x | g | f. We can chain and call functions in the actual order they are executed!

With this new syntax, the example above reads:

Isn’t that nice?

Function composition in Ruby

In Ruby we have several things which could be called a “function”, like methods, procs, blocks, and lambdas.

Let’s work with methods for now. The standard way to combine methods is simply wrapping them:

As we saw before, the more we wrap, the harder it is to understand. There are many solutions to this problem when it comes to Ruby, the most common being the Single Responsibility Principle, or SRP. Following the principle, each method must do only one thing:

While that’s not bad for readability, we now have a new alternative: #then.

Ruby composition!

The new method #then simply sends the value on the left side as parameter to the right side. Sound familiar?

Chaining is usually written like this:

Using #then is just like using | in the example above. The order in which the methods are read is the same as the order of execution.

So in this new example, Ruby builds a new Person object, then passes it as first parameter to Report#initialize, and then, because Report#initialize returns a new instance of Report, that is given as first argument to BigReport#initialize.

More gifts: Proc#>> and Proc#<<

While #then has the advantage of showing the operations in order, the syntax has quite a lot of clutter. Wouldn’t it be nice to have some syntactic sugar to help us with this?

Well, we kind of do actually! Let’s talk about Proc#>> and Proc#<<. They are binary operators which work very similarly to #then. They work on procs and methods, and always return a Proc:

Notice that because >> returns a Proc, we have to use #call to evaluate it. The equivalent using << would be:

DIY: Full composition

Now #>> and #<< are nice, but they return a Proc, and they can only be used with procs and methods. I can’t say:

Instead, I am forced to use Procs:

Also, if I want to evaluate this in-line, it gets messy:

It doesn’t behave like #then. But because Ruby is awesome, we can create our own #then operator!

Isn’t that cool? One of the things I like the most about Ruby is that you can make little Domain-Specific Languages — or DLS’s — with it. So we can make our own little language inside Ruby! And we can use that custom language to write our custom program.

NOTE: If you are into that kind of thing, then do yourself a favor and check out Lisp.

Merry Xmas!

That’s it! Hope you had some fun reading this. While programming is a job, it’s good to let your inner child play with things like this, and in my case, go back to my roots as a curious kid making computers do cool stuff.

If you happen to celebrate it, then merry Xmas! Otherwise, Happy 25th of December! Every day is worthy of celebration. 🙂

Cheers!

— Fede

Leave a Reply