ruby features i'm looking forward to
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.
My vague plan for Ruby GIL is 1) add more abstract concurrency e.g. actors 2) add warning when using threads directly 3) then remove GIL
— Yukihiro Matsumoto (@yukihiro_matz) August 1, 2014
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!