Another Japan in the World

Jun Aruga's blog.

Ruby v2.3.0 new features

Watching Matz's video, check Ruby v2.3.0 new features.
https://www.youtube.com/watch?v=E9bO1uqs4Oc&t=532

This time, only features in the video.

See all the new futures for detail.
https://github.com/ruby/ruby/blob/trunk/doc/NEWS-2.3.0

did_you_mean

When you mistake the name of the method, "Did you mean correct_method?" is displayed.
Like a Google's "Did you mean this?".

$ cat did_you_mean.rb
u = []
u.siz
$ ruby did_you_mean.rb
did_you_mean.rb:2:in `<main>': undefined method `siz' for []:Array (NoMethodError)
Did you mean?  size

Enumerable#grep_v

Like a "grep -v".

$ cat enumerable_grep_v.rb
# Enumerable#grep_v
p((1..10).grep_v 2..5)
#=> [1, 6, 7, 8, 9, 10]

res = (1..10).grep_v(2..5) do
  |v| v * 2
end
p(res)
#=> [2, 12, 14, 16, 18, 20]
$ ruby enumerable_grep_v.rb
[1, 6, 7, 8, 9, 10]
[2, 12, 14, 16, 18, 20]

Hash#fetch_values

Strict version of Hash#values_at.
If specified key does not exist, raise error.

$ cat hash_fetch_values.rb
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }

p(h.fetch_values("cow", "cat"))
#=> ["bovine", "feline"]

p(h.fetch_values("cow", "bird"))
# raises KeyError

res = h.fetch_values("cow", "bird") do |k|
  k.upcase
end
p(res)
#=> ["bovine", "BIRD"]

Numeric#positive?, negative?

$ cat numeric_positive_negative.rb
p(1.positive?)
p(0.positive?)
p(-1.positive?)

p(1.negative?)
p(0.negative?)
p(-1.negative?)

Hash comparisons (<=, <, >=, >)

$ ruby numeric_positive_negative.rb
true
false
false
false
false
true

Hash#to_proc

$ cat hash_to_proc.rb
h = { "a" => 2, "b" => 4, "c" => 6 }
# Use hash as map function
p(["a", "b", "c"].map(&h))
$ ruby hash_to_proc.rb
[2, 4, 6]

Array, Hash, Struct#dig

$ cat dig.rb
# Array, Hash, Struct#dig

data = {
  users: [
    { name: "Jun Aruga", age: 37 },
    { name: "Taro Yamada", age: 18 },
  ]
}

p(data)

# what we want to do
p(data[:users][0][:name])
# => "Jun Aruga"

# what if any of them can be nil?
p(data[:users] && data[:users][0] && data[:users][0][:name])
# => "Jun Aruga"


# shortened
p(data.dig(:users, 0, :name))
# => "Jun Aruga"

p(data.dig(:users, 1, :name))
# => "Taro Yamada"

p(data.dig(:users, 1, :abc))
# => nil
$ ruby dig.rb
{:users=>[{:name=>"Jun Aruga", :age=>37}, {:name=>"Taro Yamada", :age=>18}]}
"Jun Aruga"
"Jun Aruga"
"Jun Aruga"
"Taro Yamada"
nil

Indented here doc by (<<~)

Indented to the lowest nest line.

$ cat indented_here_doc.rb
str = <<~EOS
    header
  body
EOS
$ ruby indented_here_doc.rb
  header
body

Frozen string literals pragma

All strings in a current file become frozen

$ cat frozen_string_literals_pragma.rb
# frozen-string-literal: true

a = "abc"  # this is frozen.
a << "cde" # error!
$ ruby frozen_string_literals_pragma.rb
frozen_string_literals_pragma.rb:4:in `<main>': can't modify frozen String (RuntimeError)

Safe navigation operator

Safe navigation operator = Lonely operator. "&." LOL.

$ cat safe_navigation_operator.rb
class A
  def get(has_value)
    b = nil
    if has_value
      b = B.new
    else
      b= nil
    end
    b
  end
end

class B
  def get
    1
  end
end

# x: 1
x = A.new.get(true).get
p(x)

# error
y = A.new.get(false).get
p(y)

# z: nil
z = A.new.get(false)&.get
p(z)