今年のクリスマスにリリースされる予定の Ruby 2.7 の preview1 が 5/30 にリリースされました。
プレビュー版は、年末の正式リリースに向け、新たな機能を試し、フィードバックを集めるために提供されています。
ということで、正式リリースまでに仕様が変更になる可能性もありますが、現状の変更内容で試せるものをざっと試してみました。
Pattern Matching
今回の主要な変更点であるパターンマッチについては以前書いたものがありますので、そちらを参照いただければと思います。
REPL improvement
Ruby の REPL である irb が大幅に進化しています。入力内容に応じてインクリメンタルにシンタックスハイライトが行われたり、複数行編集がサポートされ、かなり使いやすくなっています。
メソッド参照演算子
メソッドオブジェクトの参照演算子として新たに .:
が追加されました。今までも method
というメソッドがありましたが、それと同じように使える演算子になります。例えば下記のようなクラスがあるとします。
class Sample def initialize(name) @name = name end def name(name) @name = name end def self.class_method(value) puts "Class method called with value '#{value}'." end def instance_method(value) puts "Instance method in sample '#{@name}' called with value '#{value}'." end end
今までの method
メソッドを使ってメソッドオブジェクトを取り出すには下記のように書きます。
s = Sample.new('test') cm = Sample.method(:class_method) im = s.method(:instance_method) cm.call('hoge') # => Class method called with value 'hoge'. im.call('fuga') # => Instance method in sample 'test' called with value 'fuga'. s.name('sam') im.call('fuga') # => Instance method in sample 'sample' called with value 'fuga'.
2行目、3行目を .:
を使って書き直すと下記のような形になります。
cm = Sample.:class_method im = s.:instance_method
メソッド参照演算子については下記サイトで詳しく解説されていましたので参考にさせていただきました。
デフォルトのブロックの仮引数
これまではブロックに渡される値にアクセスするための仮引数を定義する必要がありましたが、デフォルトで @1
という指定でアクセスすることができるようになります(Numbered parameters)。下記の例では array という配列の要素についてこれまでのやり方で仮引数 v
を定義してアクセスするパターン(3行目)と、デフォルトの仮引数を使用するパターン(5行目)を示しています。
array = %w(a b c d e) p array array.each {|v| puts v } puts '---' array.each { puts @1 }
実行してみると Numberd parameters を使った書き方でもこれまでと同様の出力が得られていることが確認できます。
["a", "b", "c", "d", "e"] a b c d e --- a b c d e
Numbered parameters については下記サイトでも詳しく解説されていました。
開始値省略範囲式
配列等で取り出す範囲を指定する場合、終了値を省略して最後まで全てとすることはできましたが、開始値を省略して最初の値からとすることはできませんでした。2.7では開始値も省略することができるようになります。
array = %w(a b c d e) p array[0..2] # => ["a", "b", "c"] p array[..2] # => ["a", "b", "c"]
各要素の出現回数のカウント
新たに Enumerable#tally
というメソッドが追加され、配列等に含まれている各要素の数をカウントすることができるようになります。
array = %w(apple banana apple chocolate apple banana) p array.tally # => {"apple"=>3, "banana"=>2, "chocolate"=>1}
ブロックを伴わない Proc.new と proc が deprecated
これまではブロックを渡すメソッドの中での下記4つの書き方は同じ挙動でしたが、ブロックを伴わない Proc.new
と proc
が deprecated となり、 warning が出るようになっています。代わりにブロック変数 &block
を使いましょう、という内容です。
def block_method(&block) Proc.new.call # => warning: Capturing the given block using Proc.new is deprecated; use `&block` instead # => A block is given to the method. proc.call # => warning: Capturing the given block using Proc.new is deprecated; use `&block` instead # => A block is given to the method. block.call # => A block is given to the method. yield # => A block is given to the method. end block_method { puts 'A block is given to the method.' }
ブロックを伴わない lambda はエラー
ブロックを渡すメソッドの中でブロックを伴わない lambda
の利用はエラーになるようになりました。例えば下記のようなコードを書いてみます。
def block_method(&block) lambda yield end block_method { puts 'A block is given to the method.' }
2.6.3 では warning は出るものの実行されていました。
lambda_sample.rb:2: warning: tried to create Proc object without a block A block is given to the method.
2.7 では下記のようにエラーになるようになっています。
Traceback (most recent call last): 2: from lambda_sample.rb:6:in `<main>' 1: from lambda_sample.rb:2:in `block_method' lambda_sample.rb:2:in `lambda': tried to create Proc object without a block (ArgumentError)
新元号「令和」を表す合字 U+32FF サポート
Unicode のバージョンが 12.1.0 になり、令和を表す合字が追加になっています。
irb(main):001:0> RUBY_VERSION => "2.7.0" irb(main):002:0> "\u32FF" => "㋿"
この変更は 2.6 にもバックポートされているようで、 2.6.3 でも同じように使用できました。
irb(main):001:0> RUBY_VERSION => "2.6.3" irb(main):002:0> "\u32FF" => "㋿"
2.5.5 では下記のように使用できません。
irb(main):001:0> RUBY_VERSION => "2.5.5" irb(main):002:0> "\u32FF" => "\u32FF"
Date.jisx0301, Date#jisx0301, および Date.parse で非公式に新元号に仮対応
JIS X 0301 の新しい版で正式な仕様が決定されるまでの暫定的なものとのことですが、 Date.jisx0301, Date#jisx0301, および Date.parse で非公式に新元号に仮対応されました。下記のように 2019年5月1日は令和 R
として表示されます。
irb(main):001:0> RUBY_VERSION => "2.7.0" irb(main):002:0> Date.new(2019, 5, 1).jisx0301 => "R01.05.01" irb(main):003:0> Date.parse('2019-05-01').jisx0301 => "R01.05.01"
この変更も 2.6 にバックポートされているようで、同様に使用することができます。
irb(main):001:0> RUBY_VERSION => "2.6.3" irb(main):002:0> require 'date' => true irb(main):003:0> Date.new(2019, 5, 1).jisx0301 => "R01.05.01"
2.5.5 では対応されておらず、平成 H
と表示されます。
irb(main):001:0> RUBY_VERSION => "2.5.5" irb(main):002:0> require 'date' => true irb(main):003:0> Date.new(2019, 5, 1).jisx0301 => "H31.05.01"
そのほかの変更点
今回は実際には確認しませんでしたが、他にも下記のような点が変更になっているということです。JIT については Rails との組み合わせだと逆に遅くなるということもあるようですが、今後のそれぞれの動きにも注目したいです。
断片化したメモリをデフラグするCompaction GCが導入されました。
パフォーマンスの改善: JIT
Unicode および Emoji のバージョンが 11.0.0 から 12.0.0 になりました。
Ruby のビルドに C99 に対応したコンパイラが必要になりました。
まとめ
2.7.0 の preview1 ということで、今後 preview2、 preview3、 Release Candidate を経て年末にリリースされることになります。今回は本当に簡単に試した程度で、今のところは 2.6 からバージョンアップするとしても大きな変更は必要なさそうに思っていますが、リリースまでの変更内容をキャッチアップして出来るだけスムーズに既存の環境をバージョンアップできるようにして、新たに導入された便利な機能は早く使っていけるようにしたいと思います。