Ruby2.3.0-preview1 リリースノートメモ

  • 18
    Like
  • 0
    Comment
More than 1 year has passed since last update.

3つの主要な追加feature

リリースブログにて下記3つが取り上げられています。
https://www.ruby-lang.org/en/news/2015/11/11/ruby-2-3-0-preview1-released

1. Frozen String Literal Pragma

Stringリテラルを標準でfreezeさせる Frozen String Literal Pragma の導入。指定には下記の2パターン。

コマンドラインオプションに --enable-frozen-string-literal をつける

ruby --enable-frozen-string-literal sample.rb

マジックコメント # frozen_string_literal: true をつける

# frozen_string_literal: true
"abc".reverse!
# => RuntimeError: can't modify frozen String

2. Safe navigation operator

nilのハンドルを便利にする Safe navigation operator が追加。Railsのtry!のようなもの。

obj = nil
obj&.foo
# => nil

obj = "sample"
obj&.foo
# => NoMethodError

3. did_you_mean gem

NameErrorNoMethodErrorが発生した時にメソッドをサジェストする did you mean gemが組み込まれた。

@full_name = "Sample Taro"
first_name, last_name = full_name.split(" ")
# => NameError: undefined local variable or method `full_name' for main:Object
#
#     Did you mean? @full_name
#

その他のアップデート

追加されたメソッド系を中心に取り上げます。
https://github.com/ruby/ruby/blob/v2_3_0_preview1/NEWS

Array#bsearch_index #10730

Array#bsearch(2分探索)の結果のindex番号を返す

[0, 4, 7].bsearch_index {|x| x >= 4 } # => 1
[0, 4, 7].bsearch_index {|x| x >= 6 } # => 2

Enumerable#grep_v #11049

Enumerable#grepの逆(マッチしない)の要素を集める

%w(aaa bbb ccc).grep(/b/) #=> ["bbb"]
%w(aaa bbb ccc).grep_v(/b/) #=> ["aaa", "ccc"]

grep -vコマンド欲しいよねって事から

Enumerable#chunk_while #10769

ブロックで指定した条件ごとに部分配列に分ける

# 隣り合う偶数同士、奇数同士の部分配列ごとに分ける。
[7, 5, 9, 2, 0, 7, 9, 4, 2, 0].chunk_while{|i, j| i.even? == j.even?}.to_a
# => [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]]

Hash#fetch_values #10017

Hashから複数のvaluesをfetchする

{ one: 1, two: 2, three: 3 }.fetch_values(:two, :three) #=> [2, 3]

ログ見るとメソッド名について投票あったり議論されてて面白い。

Hash#dig #11643

HashやArrayを深堀りするのにnilをうまく扱える

hash = { user: { avatar: { path: "sample.png" } } }

hash[:user][:avatar][:path]
#=> "sample.png"
hash.dig(:user, :avatar, :path)
#=> "sample.png"

hash[:user][:photo][:photo]
#=> NoMethodError
hash.dig(:user, :photo, :path)
#=> nil

Arrayにも実装

array = [1, [2, [3]]]

array[1][1][0]
#=> 3
array.dig(1, 1, 0)
#=> 3

array[1][2][3]
#=> NoMethodError
array.dig(1, 2, 3)
#=> nil

Hash#<=, Hash#<, Hash#>=, Hash#> #10984

Hashの包含関係を判定する

{ a: 1, b: 2 } <= { a: 1, b: 2 } # => true
{ a: 1, b: 2, c: 3 } <= { a: 1, b: 2 } # => false
{ a: 1, b: 2 } < { a: 1, b: 2 } # => false
{ a: 1, b: 2 } < { a: 1, b: 2, c: 3 } # => true

Hash#to_proc #11653

HashをProc化してMapに渡したりできるように

my_hash = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
my_hash.to_proc.call(:a)
# => 1

[:e, :a, :b, :f, :c, :d].map(&my_hash) 
# => [5, 1, 2, 6, 3, 4]

Procは[]でcallできるのにHashがProcにmappableじゃないよねとのことから。

Module#deprecate_constant #11398

Deprecatedなconstantに使う

TimeoutError = Timeout::Error
class Object
  deprecate_constant :TimeoutError
end

NameError#receiver #10881

NameErrorのレシーバを取得する

receiver = "receiver"
exception = receiver.doesnt_exist rescue $!

exception.receiver == receiver  # => true

Numeric#positive? Numeric#negative? #11151

数値のPositive/Negativeを判定する

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