What's new with Ruby 2.3?

Ruby 2.3-preview was released on November 11, which brings some new interesting features to the core as well as the syntax itself. Matz talked about this at RubyConf 2015.

Extract values with Hash#dig or Array#dig

Let's say you have something like this:

order = {  
 delivery_details: {
   address: {
    street: "Main 10st"
   }
  }
}

And to access the street value you would do something like:

order[:delivery_details][:address][:street]  

But there is a caveat in here, although everything works just fine, what if the address key is nil?, then you will get something like:

#NoMethodError: undefined method `[]' for nil:NilClass

If you are working with Rails you could easily do something like:

order.try(:[], :delivery_details).try(:[], :address_details).try(:[], :street)  

But that is kind of ugly isn't it?

The new #dig method can look for deeply nested keys:

order.dig(:delivery_status, :address, :street)  

If any of the attempts to access a nested key is nil, the output will be nil.

Filtering using grep

You can easily filter arrays with the grep and grep_v methods:

Using a regular expresion

names = ["Naruto", "Sasuke", "Sakura"]

names.grep(/^Sa/)  
#=> ["Sasuke", "Sakura"]

names.grep_v(/^Sa/)  
#=> ["Naruto"]

Using types

objects = ["A string", [], {}, :1, "another string"]

objects.grep(String)  
#=> ["A string", "another string"]

New Numeric predicates

Using enumerable, the Numeric class has included new predicates to know whether a number is positive or negative.

1.positive?  
#=> true

-1.negative?
#=> true

[-2, -1, 0, 1, 2].select(&:positive?)
#=> [1, 2]

Safe navigation operators

In some cases when working with conditionals, you may have something like:

# a sessions example for Rails
if user && user.email? && user.valid_password? && user.able_to_login?  
 sign_in user
end  

You wan to avoid nil objects trying to access methods, in this case the user. Thanks to the a new operator &. this is easy to achieve:

# a sessions example for Rails
if user&.email?&.valid_password?&.able_to_login?  
 sign_in user
end  

This basically works similar to the try method from Rails, on which will return nil if a method call could not be performed, and will return a nil value immediately.

If you find it hard to remember this new operator, think of it as a "lonely old man watching a dot" - Matz words not mine.

Fetch with Hash#fetch_values

This is a similar method to values_at, but not the same, here is a quick example on how this both methods work:

hash = {  
 a: 1,
 b: 2,
 c: 3
}

hash.fetch_values(:a, :b, :c)  
#=> [1,2,3]

hash.values_at(:a, :b, :c)  
#=> [1,2,3]

This may look the same to you, but what happens if we send an invalid key:

hash = {  
 a: 1,
 b: 2,
 c: 3
}

hash.fetch_values(:a, :b, :c, :d)  
#=> KeyError: key not found: :d

hash.values_at(:a, :b, :c, :d)  
#=> [1,2,3, nil]

What's next

I recommend you to read https://www.ruby-lang.org/en/news/2015/11/11/ruby-2-3-0-preview1-released/ about the new release, and while you are there, you may want to add the RSS feed.