Ruby 2.5 がリリースされたので、そろそろ Ruby 2.3 から 2.4 にしようかと思う今日この頃です。
この前 Ruby 2.5 の変更内容の記事を書きましたが、Ruby 2.4 についてちゃんと調べてなかったので今さらですが調べてみました。
元ネタは https://github.com/ruby/ruby/blob/v2_4_3/NEWS です。
長くなったので3つにわけてます。
- 条件式中での多重代入が可能
- メソッド引数で rescue 修飾子が有効
- トップレベルで return 可能
- Refinements
- 正規表現
- スレッドがデッドロックした時にバックトレースを出力
- TRUE, FALSE, NIL が deprecated
- Unicode 9.0.0
- サポートプラットフォーム
条件式中での多重代入が可能
Ruby 2.3 % ruby -W0 -e 'if (a, b = 1, 2); p [a, b]; end;' -e:1: multiple assignment in conditional if (a, b = 1, 2); p [a, b]; end; Ruby 2.4 % ruby -W0 -e 'if (a, b = 1, 2); p [a, b]; end;' [1, 2]
メソッド引数で rescue 修飾子が有効
def hoge(x) x end hoge (raise rescue nil)
Ruby 2.3 % ruby a.rb a.rb:4: syntax error, unexpected modifier_rescue, expecting ')' hoge (raise rescue nil) ^ Ruby 2.4 % ruby a.rb
なお 2.3 でも次の書き方は問題ないです。
hoge((raise rescue nil))
トップレベルで return 可能
p 123 return
Ruby 2.3 % ruby a.rb 123 a.rb:2:in `<main>': unexpected return (LocalJumpError) Ruby 2.4 123
Refinements
Symbol#to_proc で Refinements が有効
class A def hoge 123 end end module X refine A do def hoge 789 end end end using X # Ruby 2.3 [A.new].map do |x| x.hoge end #=> [789] [A.new].map(&:hoge) #=> [123] # Ruby 2.4 [A.new].map do |x| x.hoge end #=> [789] [A.new].map(&:hoge) #=> [789]
BasicObject##__send__ で Refinements が有効
# Ruby 2.3 p A.new.hoge #=> 789 p A.new.__send__(:hoge) #=> 123 # Ruby 2.4 p A.new.hoge #=> 789 p A.new.__send__(:hoge) #=> 789
Module#refine の引数にモジュールを指定可
Ruby 2.3 ではクラスしか指定できませんでした。
module M def hoge "M#hoge" end end class C include M end module X refine M do def hoge "X#hoge" end end end c = C.new c.hoge #=> "M#hoge" using X c.hoge #=> "X#hoge"
Module.used_modules 追加
現在のスコープで使用されているモジュールの一覧を配列で返します。
class C end module A refine C do end end module B refine C do end end Module.used_modules #=> [] using A Module.used_modules #=> [A] using B Module.used_modules #=> [B, A]
正規表現
\X
がUnicodeの絵文字の結合文字にも適合
s = "👨\u{1F3FF}" # 男と濃い肌色の結合文字 s =~ /\A\X\z/ #=> 0 (2.3 では nil)
正規表現エンジン Onigmo 6.1.1
非包含オペレータ (?~式)
が追加されました。
/\A(?~abc)\z/ =~ "abc" #=> nil
スレッドがデッドロックした時にバックトレースを出力
a = Mutex.new b = Mutex.new Thread.new do a.lock sleep 0.1 b.lock end b.lock sleep 0.1 a.lock sleep
Ruby 2.3
% ruby a.rb a.rb:12:in `lock': No live threads left. Deadlock? (fatal) from a.rb:12:in `<main>'
Ruby 2.4
% ruby a.rb a.rb:12:in `lock': No live threads left. Deadlock? (fatal) 2 threads, 2 sleeps current:0x0000564d7fccdf60 main thread:0x0000564d7fccdf60 * #<Thread:0x0000564d7fd01e98 sleep_forever> rb_thread_t:0x0000564d7fccdf60 native:0x00007f87af8ea640 int:0 a.rb:12:in `lock' a.rb:12:in `<main>' * #<Thread:0x0000564d7fee2cf8@a.rb:4 sleep_forever> rb_thread_t:0x0000564d80019b80 native:0x00007f87ad967700 int:0 mutex:0x0000564d7fccdf60 cond:1 a.rb:7:in `lock' a.rb:7:in `block in <main>' from a.rb:12:in `<main>'
TRUE, FALSE, NIL が deprecated
使用すると warning が出力されます。
Unicode 9.0.0
Unicdoe のバージョンが 8.0.0 から 9.0.0 になりました。
サポートプラットフォーム
FreeBSD 4 未満はサポート外になりました。