はじめに
RubyKaigi 2日目が終了しました。去年参加出来なかったので3年ぶりのRubyKaigiです。
さて、9/18(木) に Ruby 2.2.0-preview1 がリリースされているので試してみました。 いつものように NEWS から僕の分かる部分だけを紹介します。
see also: rbenv global 2.1.0-preview2 した話 - ちなみに
インストール
すでに ruby-build に登録されているので簡単にインストールできます。
$ CONFIGURE_OPTS="--enable-bundled-libyaml" rbenv install 2.2.0-preview1 $ rbenv global 2.2.0-preview1 $ ruby -v ruby 2.2.0preview1 (2014-09-17 trunk 47616) [x86_64-darwin13]
もしかして --enable-bundled-libyaml
は不要ですか。
気になった変更点
NEWSを読んで気になったところをピックアップしました。理解できていないところは都合よく気にならなかったことになっています。
言語レベルの変更
nil/true/false が frozen になった
2.1 でシンボルが frozen
になりましたが、nil
/true
/false
も frozen になりました。
# 2.1 nil.instance_variable_set(:@a, 5) p nil.instance_variable_get(:@a) #=> 5 p nil.frozen? #=> false # 2.2 nil.instance_variable_set(:@a, 5) #=> can't modify frozen NilClass (RuntimeError) p nil.frozen? #=> true
コアクラスの変更
binding#local_variables
ローカル変数の一覧が取得できるようになりました。
p binding.local_variables #=> [] a = 1 p binding.local_variables #=> [:a]
binding#receiver
呼び出したオブジェクト?
binding
の receiver
というのが何を指すのか理解出来ませんでした。
Method#receiver
と同じ結果のようでした。
class A def hoge binding end end a = A.new p a.hoge.receiver #=> #<A:0x007fb06983cef0> p a.public_method(:hoge).receiver #=> #<A:0x007fb06983cef0>
Dir#fileno
ディレクトリのファイルディスクリプタを取得出来るようになりました。
Enumerable
#slice_after が追加
Enumerable#slice_before
の逆バージョンが追加されました。
条件に一致した要素の後ろで配列を分割してチャンクを作ります。
引数としてパターンを渡した場合は ===
でマッチ、ブロックの場合は true
を返したときに分解します。
p [0,2,4,1,2,4,5,3,1,4,2].slice_before(&:even?).to_a #=> [[0], [2], [4, 1], [2], [4, 5, 3, 1], [4], [2]] p [0,2,4,1,2,4,5,3,1,4,2].slice_after(&:even?).to_a #=> [[0], [2], [4], [1, 2], [4], [5, 3, 1, 4], [2]]
min/max/min_by/max_by が取得する数を指定出来るように変更
値が大きい順に2つ取得みたいなことが出来るようになりました。
list = [5, 2, 1, 6, 9, 3] p list.max(2) #=> [6, 9]
Float#next_float、Float#prev_float
Fixnum#succ の Float 版…?
p 1.0.next_float #=> 1.0000000000000002 p 1.0.prev_float #=> 0.9999999999999999
File#birthtime、File::Stat#birthtime
ファイルの作成日を取得できるようになりました。
Pathname
にも追加されています。
インクリメンタルGC の導入
GC の更なる改善として、インクリメンタルGCが導入されました。 笹田さんのるびまの記事に詳しいです。
Rubyist Magazine - YARV Maniacs 【第 12 回】 インクリメンタル GC の導入
Kenel#itself
自分自身を返すメソッドが追加されました。 何がべんりなのか分からなかったのですがチケットを読んでたらなるほどという感じ。
p [1, 2, 3, 1, 2, 3].group_by(&:itself) #=> {1=>[1, 1], 2=>[2, 2], 3=>[3, 3]} # [1,2,3,1,2,3].group_by {|i| i } が簡潔に書けるようになっている
あと ActiveSupport 4.2 に入る予定の Object#itself
の 例 も分かりやすかったです。
実装 も単純明快。僕でも読めた。
Process 周り
Process#spawn などでリダイレクトするオプションを指定すると、今までは read モードで開いていたのが、write モードになるようです。どういう影響があるのか理解出来ていませんが非互換なようです。
Process#spawn などのプロセス生成系のメソッドが fork
よりも速い vfork
を使うようになりました。
Symbol が GC の対象
今まではシンボルは生成されるとそのプロセス内で唯一の存在になってプロセスが死ぬまで残り続けました。これは用途によってはセキュリティリスクになってしまいます。
今回の変更で、シンボルであっても使われていなければ GC されるようになりました。
Matrix#first_minor、 Matrix#cofactor
行列を扱う Matrix にも2つのメソッドが追加されました。
小行列を求める #first_minor
と余因子を求める #cofactor
です。
大学の時にもっと代数をやっておけば良かったと後悔する毎日です。
p Matrix[[1, 2, 3],[2, 3, 1],[3, 1, 2]].first_minor(0, 0) #=> Matrix[[3, 1], [1, 2]] p Matrix[[1, 2, 3],[2, 3, 1],[3, 1, 2]].cofactor(0, 0) #=> 5
Method の変更
#curry
これまでも Proc#curry
を使ってカリー化を行うことが出来ましたが、メソッドでも出来るようになるみたいです。
def add(a, b) a + b end ten_adder = method(:add).curry(2).(10) ten_adder.(5) #=> 15
#super_method
super
で呼べるメソッドを Method オブジェクトとして取得出来るようになりました。
p "string".public_method(:inspect).super_method #=> #<Method: Object(Kernel)#inspect>
非互換な変更
いくつか非互換な変更があります。 全体的に僕の理解が及ばなかったので変更が明確なGC以外は省略。
GC
GC.stat
で取得出来るハッシュのキーが一部変更になっています。以下で一覧が公開されているようです。
標準ライブラリの変更
Digest#HMAC なくなりました
OpenSSL::HMAC
を代わりに使用してください。
Etc にいくつかのメソッドが追加されました
- Etc.uname
- Etc.sysconf
- Etc.confstr
- IO#pathconf
Find/Pathname の find メソッド
ignore_error
キーワード引数を受け取れるようになった。(効果は調べていない)
Pathname#/ の追加
Pathname#+ のエイリアス。
p Pathname("cute")/"nyanco"/"wanco" #=> #<Pathname:cute/nyanco/wanco>
標準ライブラリの非互換な変更
いろいろ消えたりしていました。雑多な感じなので NEWS をご覧ください。
その他
CのAPIも Deprecated だったものが一気に消えたりしていました。
おわりに
ホテルで仕事しててつらい気持ちになったのでいつものやつをやりました。 今回は時間もなかったのであまり深く調べずに速攻分かるものだけに言及しています。 さらに、あまりお遊びをする余裕がなかったのでつまらない感じになってしまいました。 (校正していないのでタイポや間違いとかたくさんありそうです…)
今年もクリスマスは予定ないのでちゃんとします。
(明日は築地で寿司を食べつつ9時半のセッションに間に合わす予定なのですが、こんな時間なので寝坊する可能性高くて厳しい。)