概要
昨年のクリスマスに ruby2.7.0 がリリースされました
早速ですが使ってみました
とりあえず主要そうな機能と簡単に試せそうな機能について軽く触れている感じです
環境
- macOS 10.15.2
- rbenv 1.1.2
- ruby 2.7.0
ruby2.7.0 の準備
まずはインストールします
執筆時点では Homebrew に 2.7.0 がなかったので rbenv を使いました
rbenv ではすでに 2.7.0 の配信が始まっているようです
まずは ruby-build と rbenv を最新版にします
brew upgrade ruby-build rbenv
rbenv でインストール可能なバージョンの一覧を表示すると「2.7.0」があるのが確認できると思います
あとはインストールします
openssl のパスを指定していますがもしかすると不要です
rbenv が自動で最新版をインストールしてくれるっぽいです
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
rbenv install 2.7.0
ビルドが完了すれば rbenv のインストールパスにバイナリが配置されます
Downloading openssl-1.1.1d.tar.gz…
-> https://dqw8nmjcqpjn7.cloudfront.net/1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2
Installing openssl-1.1.1d…
Installed openssl-1.1.1d to /Users/hawksnowlog/.rbenv/versions/2.7.0
Downloading ruby-2.7.0.tar.bz2…
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.bz2
Installing ruby-2.7.0…
ruby-build: using readline from homebrew
Installed ruby-2.7.0 to /Users/hawksnowlog/.rbenv/versions/2.7.0
あとはメインに設定すれば OK です
rbenv global 2.7.0
rbenv version
``rbenv which ruby`` -v
=> ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19]
これを使って試していきます
case でのパターンマッチング
オフィシャルのサンプルは以下のような感じです
JSON の文字列からハッシュを作成し、そのハッシュでパターンマッチングしています
require "json"
json = <<END
{
"name": "Alice",
"age": 30,
"children": [{ "name": "Bob", "age": 2 }]
}
END
case JSON.parse(json, symbolize_names: true)
in {name: name, children: [{name: children_name, age: children_age}]}
p name
p children_name
p children_age
end
case にパターンマッチさせたいオブジェクトを指定します
そして in でパターンとなる構文を指定できます
どうやらパターンマッチングにはいくつかあるようです上記はハッシュパターンというマッチングだと理解しました
例えば以下のように自分で作成したクラスでもパターンマッチングが使えます
ハッシュパターンを使って自分で作成したクラスをパターンマッチングさせたい場合は deconstruct_keys
というメソッドを実装します
require "json"
class A
def initialize
@a = "A"
end
def deconstruct_keys(keys)
{a: @a}
end
attr_accessor :a
end
case A.new
in {a: a}
p a
else
p "ng"
end
上記の場合実行するとインスタンス変数に設定した「A」が表示されます
こんな感じで自分のクラスに対してもパターンマッチングが使えます
ちなみにアレイパターンというマッチング方式もありその場合は deconstruct
というメソッドを実装し配列を返却するようにすればアレイパターンを使ってパターンマッチングすることができます
require "json"
class A
def initialize
@a = "A"
end
def deconstruct
["C", "B", @a]
end
attr_accessor :a
end
case A.new
in ["C", "B", a]
p a
else
p "ng"
end
パターンマッチングについてはこちら が参考になりました
irb の複数行対応
例えば irb を使ってメソッドやクラスを定義した際に再度同じメソッドやクラスを定義したい場合は再度 1 行ずつ入力していました
それが 1 度の入力で済むようになっています
公式に動画あるのでそれを見るのが一番はやいと思います
以下は適当にキャプチャしたものです
rbenv でインストールした場合 irb は /Users/hawksnowlog/.rbenv/versions/2.7.0/bin/irb
にありました
Compaction GC
未検証です
とりあえず GC.compact
がどこでも呼べることは確認しています
キーワード引数に対してハッシュを与えると警告が表示される
これまではキーワード引数に対してハッシュでも渡すことができました
2.7.0 でも渡すことができますが警告が表示されるようになります
Ruby3.0 では正式に使えなくなるようです
具体的には以下の通りです
# coding: utf-8
def hoge(key: "default")
p key
end
def fuga(key: "default", key2: "default2")
p key
p key2
end
hoge
hoge(key: "value")
hoge({key: "value"}) # これは警告
fuga
fuga(key: "value", key2: "value2")
fuga({key: "value", key2: "value2"}) # これも警告
hoge(**{key: "value"}) # double splat 演算子を付与すれば警告を回避できる
fuga(**{key: "value", key2: "value2"}) # double splat 演算子を付与すれば警告を回避できる
改めて見ると確かに単一の引数に対してハッシュが渡せてしまうのは気持ち悪い感じもします
表示される警告の内容は以下のような感じでした
test.rb:13: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
test.rb:2: warning: The called method `hoge' is defined here
警告を回避するには double splat 演算子を付与するか ruby 実行時のオプションで -W:no-deprecated
を指定しても回避できます
コード内のどこかで Warning[:deprecated] = false
を指定しても回避できます
``rbenv which ruby`` -W:no-deprecated test.rb
また nil や配列の引数に対する挙動も変わっているので詳細は公式を御覧ください
範囲指定で開始番号が省略可能になった
省略した場合は 0 スタートになるようです
添字の部分には使えるようですが Range クラスのオブジェクトを作成する際にはちゃんとスタートの数字を指定しないとエラーになるようです
..
もメソッドなのでレシーバとなるオブジェクトがないから?
# coding: utf-8
ary = [0, 1, 2, 3, 4]
p ary[..3] # [0, 1, 2, 3]
ary = (..4).to_a # これはダメっぽい
tally
出現回数をカウントしてくれます
inject
や group_by
+ map
を使って自分で作る必要がなくなったのは嬉しいです
ary = ["a", "a", "b", "c", "c", "c", "c"]
p ary.tally # {"a"=>2, "b"=>1, "c"=>4}
令和対応
合字の「㋿」に対応しました
p 0x32ff.chr("utf-8")
確かに古い Ruby だと表示されませんでした
その他細かい点
公式を見てください
最後に
簡単ですが Ruby2.7.0 に触れてみました
ほんの一部しか紹介できておらずまだまだたくさんの機能が追加されたので試してみてください
細かく触っていないのであれですがインパクトがあったのは irb のアップデートだったかなという印象です
詳細はすべて Feature Request の Issue でやり取りが公開されているのでそれを確認するのが早いと思います