I’ve been exploring what’s next for ruby, and now that ruby 2.3.0-preview1 is out, here’s a quick look at what caught my eye.

$ ruby --version
ruby 2.3.0dev (2015-11-11 trunk 52540) [x86_64-linux]

the “safe navigation” & operator

The safe navigation operator was inspired by groovy, and allows you to simplify code such as

zoo = Zoo.new
zoo && zoo.animals && zoo.animals.first

into

zoo&.animals&.first

If any of the return values in the “chain” are nil, then nil is returned, otherwise, ruby continues sending the next message.

Simple, and to the point. I like it!

Note that the safe navigation it does not interact with [] syntax sugar, for instance when indexing an hash:

values&.[:foo] # error
SyntaxError: unexpected '[', expecting '('
values&.[:foo]
         ^

You’ll have to unsugar the method call:

values&.[](:foo) # works

frozen string literals

In ruby 3.0, the plan is for strings to be immutable by default. The first step towards that path is a command-line option that optionally enables that behavior for ruby 2.3:

hello = "hello world"
hello['world'] = 'ruby'
puts hello

Running the example:

$ ruby immutable.rb
hello ruby

$ ruby --enable=frozen-string-literal immutable.rb
immutable.rb:2:in `[]=': can't modify frozen String (RuntimeError)
        from immutable.rb:2:in `<main>

Immutable strings have a number of concurrency and efficiency advantages, and are the standard in many other programming languages (such as Java), so it’s nice to see them make an appearance in ruby.

did_you_mean enabled by default

The did_you_mean gem is now bundled and should be enabled by default. It did not load for me, but after a manual installation I was greeted with success:

class Zoo
  def animals
    [:penguin, :lion]
  end
end

Zoo.new.animalZ

Running the example:

$ ruby zoo.rb
zoo.rb:7:in `<main>': undefined method `animalZ' for #<Zoo:0x00000000c97a70> (NoMethodError)

    Did you mean? animals

It’s a very minor addition, but it’s one of those small niceties that can draw a smile during your daily ruby adventures.

hash comparison

In previous ruby versions, you could check if two hashes were the same:

{lions: 'enough', penguins: 'lots'} ==
  {lions: 'enough', penguins: 'lots'}
=> true

But what if you wanted to check if a hash contained another? Well, previously you’d have to convert them into sets:

Set.new({lions: 'enough', penguins: 'lots'}) >
  Set.new({lions: 'enough'})
=> true

In ruby 2.3 you’ll be able to compare sets directly:

{lions: 'enough', penguins: 'lots'} > {lions: 'enough'}
=> true

Marvelous!

Thanks to Oliver Lacan for his awesome writeup of the feature.

looking ahead: goodbye to the GIL

MRI, the default ruby implementation, employs a lock called the global interpreter lock – GIL to her friends. This lock protects each executing ruby thread so that at any given moment only one thread is allowed to be executing ruby code.

This lock allows a number of simplifications and optimizations in the way the ruby internals are implemented, but is increasingly outdated given how even phones will soon have 10-core cpus.

The lack of real multi-threading has made ruby greatly lag behind other languages, and I’m really interested in seeing the ruby ecosystem successfully transition to a GIL-less model.

To tackle this, Matz and the ruby team have been working for some time to remove the GIL, and, beyond that, to offer powerful and easy-to-use tools for multi-threaded programming.

One such proposal is the stream operator, |>, that allows multiple components to be joined in a pipeline. It’s still under heavy work, but if you’re interested, you can check out the current implementation and Matz’s recent presentation on ruby 3.0.

on the next episode!

I recently discovered the crystal programming language, a ruby-inspired language that tries to keep ruby’s awesomeness, but make it compilable down to very efficient machine code.

I’ve been itching to take it for a spin, so maybe next time!