Here are a few ruby tricks I’ve collected over the years. They’ve all been tested with ruby 2.5.

Dynamically prefilled array

You’ve probably used:

Array.new(4)
 => [nil, nil, nil, nil] 

or even:

Array.new(4, '*')
 => ["*", "*", "*", "*"]

But did you know you can dynamically prefill an array:

Array.new(4) { rand 42 }
 => [33, 14, 13, 18]

or even use the element index to fill the array:

Array.new(4) { |index| 2**index }
 => [1, 2, 4, 8]

Create a new hash from an array

If you have an array:

arr = [:key_1, 'value 1', :key_2, 'value 2']

you can create a hash from this array by doing:

Hash[*arr]
 => {:key_1=>"value 1", :key_2=>"value 2"}

Of course, if you have an array of arrays like: [[:key_1, 'value 1'], [:key_2, 'value 2']] in ruby 2.1+, you can convert it to a hash with:

[[:key_1, 'value 1'], [:key_2, 'value 2']].to_h
 => {:key_1=>"value 1", :key_2=>"value 2"}

Boolean operator with non-Boolean variables

var_1 ||= 'foo' assigns 'foo' to var_1 if var_1 had a “falsy” value, but do you know what var_1 &&= 'bar' does?

var_1 &&= 'bar'
 => nil
var_1 = 'foo'
 => "foo"
var_1 &&= 'bar'
 => "bar"

It’s the opposite! It assigns a new value to var_1 if it had a “truthy” value.

A more useful example is:

var_1 = 'foo'
var_1 &&= var_1 + 'bar'
 => "foobar"

which is equivalent to var_1 = var_1 + 'bar' if var_1

Quick HTTP server

Python is known to be able to start an HTTP server in one line (e.g.: python -m http.server 8000). Well, you can do the same in ruby:

ruby -run -e httpd . -p 8000

This starts an HTTP WEBrick server on port 8000. It serves the files in the current directory and sub-directories and you can monitor the HTTP requests from the command line.

Source: @n0kada and @tenderlove on Twitter.

Hash#fetch

If you have a hash h = { key_1: 'value 1', key_2: 'value 2' }, you can access 'value 2' by calling h.fetch(:key_2), but obviously you could simply call h[:key_2]. However, another use of Hash#fetch is how to treat missing keys by passing a block to it:

h[:key_3]
 => nil
h.fetch(:key_3) { |key| "#{key} is missing" }
 => "key_3 is missing"

Unitary operation on a list

This one is a bit niche and not quite as readable:

[0, 1, -2, 8, -42].map(&:-@)
 => [0, -1, 2, -8, 42]
[true, false, true, true, false].map(&:!@)
 => [false, true, false, false, true]

works too. You got the idea.

More common tricks

Extract nested hash values

{ a: { b: { c: 'value' } } }.dig(:a, :b, :c)
 => "value"
{ a: { b: { c: 'value' } } }.dig(:a, :missing, :c)
 => nil

Extract a value in a String with a regex

"Lorem ispum 'value 1' dolor sit amet"[/'.+'/]
 => "'value 1'"

Safe navigation operator

Added in ruby 2.3, it safeguards against the following:

var_1 = nil
var_1.length
 # raises NoMethodError (undefined method `length' for nil:NilClass)
var_1&.length
 => nil

You can also “navigate” safely with it:

var_1 = nil
var_1&.length&.to_s
 => nil

Underscore

I use that one with ruby REPLs a lot.

Let’s say you run the following in IRB:

BlackBox.compute
 => 42

You didn’t save the return value. Instead of having to recompute the value with var_1 = BlackBox.compute, you can simply use the underscore variable _:

BlackBox.compute
 => 42
var_1 = _
 => 42

_ contains the last return value.