先日Rails5.0(Ruby2.3,Ruby2.4)の新機能勉強会を開催したのでその際の資料をアップします。
本記事は、Ruby2.3 の主な新機能についてです。
- 発表スライド
- Ruby 2.3の主な新機能
- 1. 【重要!】nil でもメソッド呼び出しがエラーにならない safe navigation operator(ぼっちオペレーター)
- 2. 合致しない要素を返す Enumerable#grep_v
- 3. 複数の値をまとめてfetchする Hash#fetch_values
- 4. 数値の正負を判別する Numeric#positive?, negative?
- 5. 非推奨となった定数を参照時に警告を出す Module#deprecate_constant
- 6. エラー発生時に呼び出されたオブジェクトを取得する NameError#receiver
- 7. ヒアドキュメント内のインデントを取り除いてくれる <<~ (squiggly heredoc)
- 勉強会では紹介しなかった新機能
- 8. ハッシュをProc化できる Hash#to_proc
- 9. did_you_mean gemの標準添付
- 10. バイナリサーチを使って配列のindexを検索する Array#bsearch_index
- 11. 隣り合う要素が条件を満たせば同じグループとする Enumerable#chunk_while
- 参考情報
- 所感
30代未経験でもOK! IT/WEBエンジニアにおすすめの転職エージェント/プログラミングスクール比較 - 新米パパの育児留学
全くの未経験からIT/Webエンジニアに転職した私(30代)のロードマップ - 新米パパの育児留学
全くの未経験からIT/Webエンジニアに転職した私(30代)のロードマップ - 新米パパの育児留学
GEEKLYのIT・WEB・ソーシャルゲーム業界への転職支援サービス
発表スライド
Ruby 2.3の主な新機能
1. 【重要!】nil でもメソッド呼び出しがエラーにならない safe navigation operator(ぼっちオペレーター)
- Railsの
Object#try!
のように、オブジェクトがnil
でもエラーを恐れずメソッドが呼び出せる obj&.foo
のように書き、obj
がnil
であれば、foo
の戻り値がnil
になるtry!
と同様にメソッドが実装されていないとエラーが起きる&.
は rubyのオペレータなので、メソッドコールであるtry!
よりも速い- ぼっちオペレーターが主流
> nil.try(:book) #=> nil > nil.try!(:book) #=> nil > nil&.book #=> nil > "foo".try(:book) #=> nil > "foo".try!(:book) NoMethodError: undefined method 'book' for "foo":String > "foo"&.book NoMethodError: undefined method 'book' for "foo":String
2. 合致しない要素を返す Enumerable#grep_v
- grepコマンドの-vオプションと同等の役割
> list = %w(foo bar baz) #=> ["foo", "bar", "baz"] > list.grep_v(/ba/) #=> ["foo"] > list.grep(/ba/) #=> ["bar", "baz"]
3. 複数の値をまとめてfetchする Hash#fetch_values
- 該当のキーが検出された場合のみ、キーに対する値の配列を返す
- 値が無かった場合、
#values_at
はnil
を返すのに対して、#fetch_values
は例外KeyError
を返す。
> h = { foo: 1, bar: 2, baz: 3} #=> {:foo=>1, :bar=>2, :baz=>3} > h.fetch_values(:foo, :bar) #=> [1, 2] > h.values_at(:foo, :none) #=> [1, nil] > h.fetch_values(:foo, :none) KeyError: key not found: :none
4. 数値の正負を判別する Numeric#positive?, negative?
- positive?: 数値が正の値の場合
true
、それ以外ならfalse
- negative?: 数値が負の値の場合
true
、それ以外ならfalse
> 1.positive? #=> true > -1.positive? #=> false > 1.negative? #=> false > -1.negative? #=> true
5. 非推奨となった定数を参照時に警告を出す Module#deprecate_constant
deprecate_constant
として非推奨となった定数を指定すると、当該定数を参照時に警告を出力
require 'timeout' TimeoutError # warning: constant ::TimeoutError is deprecated FOO = 1 class Object deprecate_constant :FOO end FOO # warning: constant ::FOO is deprecated
6. エラー発生時に呼び出されたオブジェクトを取得する NameError#receiver
- NameError や NoMethodError 発生時に、呼び出されたオブジェクト(レシーバ)を取得する
begin "foo".to_ss rescue => e puts e.receiver end #=>foo
7. ヒアドキュメント内のインデントを取り除いてくれる <<~ (squiggly heredoc)
- Rubyのヒアドキュメント
<<-
を使うと、ヒアドキュメント内のインデントはそのままスペースやタブとして残っていた <<~
を使うとstrip_heredoc
と同様に、ヒアドキュメント内のインデントを取り除いてくれる
[railsでの実装:strip_heredoc
メソッドとしてあった]
# <<- を使うと、ヒアドキュメント内のインデントがそのままスペースとして残ってしまう text_with_legacy_heredoc = <<-TEXT This would contain specially formatted text. That might span many lines TEXT #=> " This would contain specially formatted text.\n That might span many lines\n" # Railsのstrip_heredocを使うと、インデントのスペースを取り除くことができる text_with_strip_heredoc = <<-TEXT.strip_heredoc This would contain specially formatted text. That might span many lines TEXT #=> "This would contain specially formatted text.\nThat might span many lines\n" # <<~ を使うとstrip_heredocと同じようにインデントのスペースを取り除いてくれる text_with_squiggly_heredoc = <<~TEXT This would contain specially formatted text. That might span many lines TEXT #=> "This would contain specially formatted text.\nThat might span many lines\n"
勉強会では紹介しなかった新機能
8. ハッシュをProc化できる Hash#to_proc
- ハッシュをProc化することで引数にハッシュを渡したりすることができる
str_ids = Bookmark.where(cond_a).order(hoge_cond).limit(n).pluck(:store_id) # 1. あるソートで str_id の配列を取る strs_by_id = Store.where(cond_b).index_by(&:id) # 2. ある条件で id を key にした str オブジェクトをたくさんもってくる str_ids.map(&strs_by_id) # 2. で作ったハッシュから 1. で指定したソート順でオブジェクトの配列を取得
9. did_you_mean gemの標準添付
- NameError や NoMethodError が発生した際に正しい名前の候補を表示してデバッグしやすくする
[railsでの実装:なし]
> "foo".uppcase NoMethodError: undefined method 'uppcase' for "foo":String Did you mean? upcase upcase!
10. バイナリサーチを使って配列のindexを検索する Array#bsearch_index
- バイナリサーチ(二分探索)のアルゴリズムを使って、オブジェクトを検索するメソッド
bsearch
が以前からあった bsearch_index
は見つかった要素そのものではなく、その要素のindexを返すbsearch_index
は大きな配列であればindex
よりも速く検索できる場合があるバイナリサーチ(bsearch_index) = O(log2 n)
- 線形探索(index) = O(n)
[railsでの実装:なし]
> [ "a", "b", "c", "d", "e" ].bsearch { |x| x > "a" } #=> "b" > [ "a", "b", "c", "d", "e" ].bsearch_index { |x| x > "a" } #=> 1 > [ "a", "b", "c", "d", "e" ].index { |x| x > "a" } #=> 1
11. 隣り合う要素が条件を満たせば同じグループとする Enumerable#chunk_while
- 隣り合う要素が条件を満たせば同じグループとする
slice_when
でも同じことが実現できますが、「隣り合う要素が条件を満たさなくなったら新しいグループに切り替える」というchunk_while
とは逆の条件
[railsでの実装:なし]
> data = [7, 5, 9, 2, 0, 7, 9, 4, 2, 0] #=> [7, 5, 9, 2, 0, 7, 9, 4, 2, 0] > data.chunk_while { |i, j| i.even? == j.even? }.to_a #=> [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]] > data.slice_when { |i, j| i.even? != j.even? }.to_a #=> [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]] > data.slice_when { |i, j| i.even? == j.even? }.to_a #=> [[7], [5], [9, 2], [0, 7], [9, 4], [2], [0]]
参考情報
公式情報
参考ブログ
所感
safe navigation operator(ぼっちオペレーター)
は便利だし使う場面多そう。"did_you_mean gemの標準添付"は初心者がタイポでハマるのを助けてくれるから嬉しい。
GEEKLYのIT・WEB・ソーシャルゲーム業界への転職支援サービス
あわせて読みたい記事
mochikichi.hatenablog.com mochikichi.hatenablog.com mochikichi.hatenablog.com mochikichi.hatenablog.com