Skip to content

Commit fb3b9ec

Browse files
committed
New features in ruby 2.3
1 parent d89c1e4 commit fb3b9ec

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

ruby/new-features-in-ruby-2.3.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# New features in ruby 2.3
2+
3+
This update brings several new additions to core classes in ruby as well as some new syntax. Here are a few of the new additions coming in ruby 2.3:
4+
5+
### 1. Extract values with Array#dig and Hash#dig
6+
7+
The new #dig instance methods provide concise syntax for accessing deeply nested data. For example:
8+
9+
```ruby
10+
user = {
11+
user: {
12+
address: {
13+
street1: '123 Main street'
14+
}
15+
}
16+
}
17+
18+
user.dig(:user, :address, :street1) # => '123 Main street'
19+
20+
results = [[[1, 2, 3]]]
21+
22+
results.dig(0, 0, 0) # => 1
23+
```
24+
25+
Both of these methods will return nil if any access attempt in the deeply nested structure returns nil:
26+
```ruby
27+
user.dig(:user, :adddresss, :street1) # => nil
28+
user.dig(:user, :address, :street2) # => nil
29+
```
30+
31+
### 2. Grep out the inverse of a pattern with Enumerable#grep_v
32+
33+
This method is the inverse of the Enumerable#grep method. The grep method and its inverse provide several powerful ways to filter enumerables:
34+
Filtering by regular expression
35+
36+
```ruby
37+
friends = %w[John Alain Jim Delmer]
38+
39+
j_friends = friends.grep(/^J/) # => ["John", "Jim"]
40+
others = friends.grep_v(/^J/) # => ["Alain", "Delmer"]
41+
```
42+
43+
Filtering by types
44+
```ruby
45+
items = [1, 1.0, '1', nil]
46+
47+
nums = items.grep(Numeric) # => [1, 1.0]
48+
others = items.grep_v(Numeric) # => ['1', nil]
49+
```
50+
51+
### 3. Fetching multiple values with Hash#fetch_values
52+
53+
Sometimes Hash#fetch is a better choice than Hash#[] when you want to write more strict code. You can also access multiple values from a hash using Hash#values_at, but there wasn’t a strict equivalent to values_at until ruby 2.3:
54+
55+
```ruby
56+
values = {
57+
foo: 1,
58+
bar: 2,
59+
baz: 3,
60+
qux: 4
61+
}
62+
63+
values.values_at(:foo, :bar) # => [1, 2]
64+
values.fetch_values(:foo, :bar) # => [1, 2]
65+
66+
values.values_at(:foo, :bar, :invalid) # => [1, 2, nil]
67+
values.fetch_values(:foo, :bar, :invalid) # => KeyError: key not found: :invalid
68+
```
69+
70+
### 4. Positive and negative predicates for Numeric#positive? and Numeric#negative?
71+
Numeric values now have predicate methods that check if the subject is positive or negative. This can be useful if you want to filter an enumerable:
72+
```ruby
73+
numbers = (-5..5)
74+
75+
numbers.select(&:positive?) # => [1, 2, 3, 4, 5]
76+
numbers.select(&:negative?) # => [-5, -4, -3, -2, -1]
77+
```
78+
79+
### 5. Hash superset and subset operators Hash#<=, Hash#<, Hash#>=, and Hash#>
80+
These methods lets you compare hashes to see if they are subsets or proper subsets of each other. For example:
81+
```ruby
82+
small = { a: 1 }
83+
medium = { a: 1, b: 2 }
84+
large = { a: 1, b: 2, c: 3 }
85+
different = { totally: :different }
86+
87+
{ a: 1, b: 2 } > { a: 1 } # => true
88+
{ a: 1 } > { a: 1 } # => false
89+
{ b: 1 } > { a: 1 } # => false
90+
{ a: 1, b: 2 } < { a: 1, b: 2, c: 3 } # => true
91+
```
92+
93+
### 6. Convert a hash to a proc with Hash#to_proc
94+
Now you can use a hash to iterate over an enumerable object:
95+
```ruby
96+
hash = { a: 1, b: 2, c: 3 }
97+
keys = %i[a c d]
98+
99+
keys.map(&hash) # => [1, 3, nil]
100+
```
101+
102+
Avoid nil related errors with the safe navigation operator
103+
104+
### 7. New syntax for accessing deeply nested objects safely without accidentally triggering a dreaded NoMethodError on nil.
105+
The syntax looks like this:
106+
```ruby
107+
require 'ostruct'
108+
user&.address&.street&.first_line
109+
```
110+
111+
where each instance of &. is similar to ActiveSupport’s Object#try method. Basically, if a nil value is encountered, then each method call will not be attempted and instead the nil value will be returned immediately.
112+
Experimental frozen string pragma
113+
114+
You’ve probably heard that strings will be frozen by default in ruby 3. Ruby 2.3 lets you specify a pragma which enables this by default:
115+
```ruby
116+
$ ruby -v
117+
ruby 2.3.0preview1 (2015-11-11 trunk 52539) [x86_64-darwin14]
118+
$ cat default.rb
119+
# frozen_string_literal: false
120+
121+
puts "Hello world".reverse!
122+
$ ruby default.rb
123+
dlrow olleH
124+
$ cat enabled.rb
125+
# frozen_string_literal: true
126+
127+
puts "Hello world".reverse!
128+
$ ruby enabled.rb
129+
enabled.rb:3:in `reverse!': can't modify frozen String (RuntimeError)
130+
from enabled.rb:3:in '<main>'
131+
```
132+
Alternatively, you can also enable and disable this using the command line argument --enable=frozen-string-literal

0 commit comments

Comments
 (0)