Ruby 2.5.0リリース!NEWSを読んでみた

Ruby 2.5.0リリースおめでとうございます。

取り急ぎNEWSを斜め読みしてみました。誤りを含んでいるかもしれないので気づき次第修正します。
主要な変更点についてはCRubyコミッタの村田さんによる記事「Ruby 2.5.0 リリース直前!何が変わるのかもう一度おさらいしておこう!」で詳しく解説されています。NEWSには載っていませんが、以下の記事で解説されているNODEとGCの切り離しも大きな変更だと思います。


2.4.0リリース以降の変更点

言語面の変更

  • トップレベルの定数参照を削除(Feature #11547

  • do/endブロック内でrescue/else/ensureを利用できるようになった(Feature #12906

  • 文字列の式展開にrefinementsが効くようになった(Feature #13812

コアクラスの変更点(主なもののみ)

Array

Data

  • 非推奨化: C拡張の基本クラスであり、Rubyレベルに公開する必要がないため(Feature #3072

Exception

  • 新メソッド:
    • Exception#full_messageで例外のString表現を取り出せるようになった: キャッチされていない例外をRubyが出力するときと同じフォーマットが使われる(Feature #14141 — experimental)

Dir

  • Dir.globに新しいオプションキーワード引数:baseを追加 (Feature #13056
  • 次のメソッドでGVLが解放されるようになった: Dir.chdir(ブロック引数なしの場合)、Dir.openDir.newDir.mkdirDir.rmdirDir.empty?
  • 新メソッド:

Enumerable

  • 以下のメソッドで引数に正規表現パターンを直接与えられるようになった (Feature #11286
    • Enumerable#any?
    • Enumerable#all?
    • Enumerable#none?
    • Enumerable#one?

追記: 以下も渡せるようです。#===に渡せるものならいけそうです。

[1, 2, 3].any?(1) # => true
[1, 2, 3].any?(Numeric) # => true

Rubyの===演算子についてまとめてみた

File

  • File.open:newlineオプションを与えると暗黙でテキストモードになるようになった(bug #13350
  • File::Constants::TMPFILEオプション付きで開いたファイルがFile#pathIOErrorがraiseされるようになった(Feature #13568
  • GVL(Giant VM Lock)がFile.statFile.exist?およびrb_stat()を使うその他のメソッドで解放されるようになった(bug #13941
  • File.renameでGVLが解放されるようになった(Feature #13951
  • 以下のメソッドで秒より細かいタイムスタンプをWindows 8以降でサポート(Feature #13726
    • File::Stat#atime
    • File::Stat#mtime
    • File::Stat#ctime
  • File::Stat#inoFile.indentical?でWindows 8.1以降のReFS 128bit inoをサポート(Feature #13731
  • 以下のメソッドでGVLが解放されるようになった
    • File.readable?
    • File.readable_real?
    • File.writable?
    • File.writable_real?
    • File.executable?
    • File.executable_real?
    • File.mkfifo
    • File.readlink
    • File.truncate
    • File#truncate
    • File.chmod
    • File.lchmod
    • File.chown
    • File.lchown
    • File.unlink
    • File.utime
    • File.lstat
  • 新メソッド:

Hash

IO

IOError

  • IO#closeが例外をraiseする場合のメッセージを「stream closd」から「stream closed in another thread」に改良した(bug #13405

Integer

  • Integer#stepでstep値が#>0と比較できない場合に#coerceメソッドからのエラーを隠蔽しなくなった(Feature #7688
  • Integer#roundInteger#roundInteger#floorInteger#ceilInteger#truncateが常にIntegerを返すようになった(bug #13420
  • Integer#powが指数算出用の剰余(modulo)を引数に取れるようになった(Feature #12508)(Feature #11003
  • 新メソッド

Kernel

Method

  • 新メソッド:
    • Method#===Proc#===と同様Method#callを呼ぶ)(Feature #14142

Module

  • Module#attrModule#attr_accessorModule#attr_readerModuleattr_writerがpublicになった(Feature #14132
  • Module#define_methodModule#alias_methodModule#undef_methodModule#remove_methodがpublicになった(Feature #14133

Numeric

  • 数値比較演算子(<<=>=>)が内部で#coerceメソッドからの例外を隠蔽しないようになった: coertionが不可能な場合は#coercenilを返す(Feature #7688

Process

  • getrusage(2)が存在する場合のProcess.timesの精度を改善(Feature #11952
  • 新メソッド:

Range

  • Range#initializeで開始値と終了値の#<=>の比較で“bad value for range” ArgumentErrorがraiseされた場合に例外を隠蔽しないようになった: 今後は#<=>呼び出しからの例外をそのまま通す(Feature #7688

Regexp

  • Onigmo 6.1.3-669ac9997619954c298da971fcfacccf36909d05にアップデート
  • 非包含演算子(absence operator)をサポート(#82
  • Unicodeの絵文字関連の文字プロパティを新たに5つサポート

RubyVM::InstructionSequence

  • 新メソッド:
    • RubyVM::InstructionSequence#each_child
    • RubyVM::InstructionSequence#trace_points

String

  • unfreezeされた文字列がString#-@でdupされないようになった: 既にfrozenされた文字列については互換性のため動作は変更されない(Feature #13077

  • -“リテラル”(String#-@)が同じオブジェクトを返すよう最適化された(ruby 2.1以降の"リテラル".freezeと同じ)(Feature #13295

  • String#casecmp/String#casecmp?は引数が文字列でない場合にTypeErrorをraiseする代わりにnilを返すようになった(bug #13312
  • String#start_with?で正規表現を引数に取れるようになった(Feature #13712
  • 新メソッド
    • String#delete_prefixString#delete_prefix!Feature #12694
    • String#delete_suffixString#delete_suffix!Feature #13665
    • 書記素(grapheme)クラスタを列挙するString#each_grapheme_clusterString#grapheme_clustersを追加(Feature #13780
    • String#undumpString#dumpされた文字列をunescapeする)(Feature #12275

Struct

  • Struct.newkeyword_init: trueオプションを与えるとメンバをキーワード引数として初期化できるようになった(Feature #11925

RegexpString

  • Unicodeバージョンを9.0.0から10.0.0にアップデート(Feature #13685

Thread

  • Thread#name=で設定したdescriptionセットがWindows 10で表示されるようになった
  • 新メソッド
  • Thread.report_on_exceptionがデフォルトでtrueになった: unhandled例外の終了スレッドを$stderrに出力する(Feature #14143

Time

  • Time#atで、第2引数の単位を第2引数で指定できるようになった(Feature #13919

KeyError

FrozenError

Stdlibの更新(主なもののみ)

Bundler

BigDecimal

  • BigDecimal 1.3.4に更新
  • 以下の機能を追加:
    • BigDecimal::VERSION
  • 以下の機能を非推奨化(1.4.0で削除予定)
    • BigDecimal.new
    • BigDecimal.ver
  • BigDecimal#clone#BigDecimal#dupで新規インスタンスを作成せずにレシーバ自身を返すようになった。

Coverage

  • ブランチカバレッジとメソッドカバレッジの測定をサポート(Feature #13901)。ブランチカバレッジはどのブランチが実行されていてどれが実行されていないかを通知する。メソッドカバレッジはどのメソッドが呼び出され、どのメソッドが呼び出されていないかを通知する。この新機能を使ってテストスイートを実行すると、どのブランチやメソッドがテストで実行されているかがわかるようになり、テストスイートのトータルなカバレッジをより厳密に評価できるようになる。

Coverage.startオプションで測定対象を指定できる。

Coverage.start(lines: true, branches: true, methods: true)

Rubyファイルの読み込みがある程度進むと、Coverage.resultでカバレッジの結果を取れる。

Coverage.result
#=> { "/path/to/file.rb"=>
#     { :lines => [1, 2, 0, nil, ...],
#       :branches =>
#         { [:if, 0, 2, 1, 6, 4] =>
#             { [:then, 1, 3, 2, 3, 8] => 0,
#               [:else, 2, 5, 2, 5, 8] => 2
#             }
#         },
#       :methods => {
#          [Object, :foo, 1, 0, 7, 3] => 2
#       }
#     }
#   }

結果のうち行カバレッジは変更されない(数値を含む単なるarray)。つまり各行のカウントは実行されたかnilかを表し、その行とは関連しない。

ブランチカバレッジの結果は次の形式を取る。

{ (jump base) => { (jump target) => (counter) } }

jump basejump targetはフォーマットされる。

[type, unique-id, start lineno, start column, end lineno, end column]

たとえば[:if, 0, 2, 1, 6, 4]は、2行目1カラム目から6行目4カラム目までの範囲のifステートメントを示し、[:then, 1, 3, 2, 3, 8]は3行目2カラム目から3行目8カラム目までの範囲のthen句を示す。

メソッドカバレッジは次の形式を取る。

{ (method key) => (counter) }

method keyはフォーマットされる。

[class, method-name, start lineno, start column, end lineno, end column]

たとえば[Object, :foo, 1, 0, 7, 3]は1行目0カラム目から7行目3カラム目の範囲にあるObject#fooを示す。先の例ではObject#fooは2回呼び出されている。

メモ: 互換性を保つため、オプションを付けないCoverage.startは行カバレッジだけを返し、オプションを付けないCoverage.resultは従来のフォーマットで結果を返す。

Coverage.result
#=> { "/path/to/file.rb"=> [1, 2, 0, nil, ...] }

DRb

  • ACL::ACLEntry.newIPAddr::InvalidPrefixErrorが抑制されないようになった

ERB

  • ERB#result_with_hashを追加: Hashオブジェクトで渡されたローカル変数を持つテンプレートのレンダリング(Feature #8631
  • erbコマンドでテンプレートファイルのデフォルトエンコーディングをASCII-8BITからUTF-8に変更(bug #14095
  • trim_modeが指定されている場合に改行(carriage return)が正しく削除されるようになり、Windowsで重複した空行が削除されるようになった(bug #5339)(bug #11464

IPAddr

  • IPAddrで不正なアドレスマスクを受け取らなくなった(bug #13399
  • IPAddr#ipv4_compatIPAddr#ipv4_compat?が非推奨化(bug #13769
  • 新メソッド追加:

IRB

  • バックトレースやエラーメッセージの逆順出力(Feature #8661 — experimental)
  • (experimental)binding.irbで自動的にirbがrequireおよび実行されるようになった(Feature #13099
  • binding.irbの呼び出し時にソースの前後が表示されるようになった(Feature #14124

Matrix

  • 新メソッド:
    • Matrix.combineMatrix#combineFeature #10903
    • Matrix#hadamard_product
    • Matrix#entrywise_product

Net::HTTP

  • Net::HTTP.newno_proxyパラメータをサポート(Feature #11195
  • Net::HTTP#min_versionNet::HTTP#max_versionFeature #9450
  • HTTPステータスクラスを追加
  • Net::HTTP::STATUS_CODESがHTTP Status Code Repositoryとして追加(Misc #12935
  • Net::HTTP#proxy_userNet::HTTP#proxy_passで、システムの環境変数がマルチユーザーで安全な場合にhttp_proxy環境変数を反映するようになった(bug #12921

open-uri

  • URI.openメソッドがopen-urlのKernel.openのエイリアスとして定義された。open-urlのKernel.openは今後非推奨化。

OpenSSL

  • Ruby/OpenSSLを2.0から2.1にアップデート。変更点はext/openssl/History.mdの「Version 2.1.0」に記載。

Pathname

Psych

  • Psych 3.0.2にアップデート
    • フォールバックオプションをキーワード引数に変換(#342
    • Psych.loadPsych.safe_loadJSON#parseと同様の:symbolize_namesオプションを追加(#333)(#337
    • Psych::Handler#event_locationを追加(#326
    • frozen string literal = trueに設定(#320
    • 時間のdeserializeでタイムゾーンオフセットを保持(#316
    • syck gemの非推奨メソッドエイリアスを削除(#312

RbConfig

  • RbConfig::LIMITS: C型の上限を指定。rbconfig/sizeofrequireすることで利用可

Ripper

  • Ripper::EXPR_BEGなど(Ripper#stateで使用)
  • メソッド追加
    • Ripper#stateスキャナのステートを指定(Feature #13686

RDoc

  • RDoc 6.0.1にアップデート
  • IRBベースのlexerをRipperに置き換えてドキュメント生成速度を大幅に向上(#512
    • ドキュメント生成速度が大幅に向上。
    • 今後の新文法のサポートが容易に。
  • 過去数年分のRubyの新機能を多数サポート
  • frozen_string_literal: trueの利用: ドキュメント生成時間を5%短縮。
  • did_you_meanのサポート。

Rubygems

SecureRandom

  • 新メソッド:
    • SecureRandom.alphanumeric

Set

StringIO

  • StringIO#writeで複数の引数を扱えるようになった

StringScanner

  • 新メソッド:
    • StringScanner#size/StringScanner#captures/StringScanner#values_atFeature #836

WEBrick

Zlib

  • Zlib::GzipWriter#writeで複数の引数を扱えるようになった
  • Procオブジェクトをbodyレスポンスとしてサポート(Feature #855
  • RubyGemとしてリリース(Feature #13173
  • Kernel#openで意図しない振る舞いを回避(Misc #Kernel#open

互換性の問題(featureやbug修正を除く)

  • Net::HTTP
    • Net::HTTP#startがデフォルトで:ENVp_addrに渡すようになった(bug #13351)これを回避するには明示的にnilを渡す
  • Socket
    • IO#read_nonblockIO#write_nonblockO_NONBLOCKファイルデスクリプションフラグを副作用として設定しないようになった(Linuxのみ)(Feature #13362
  • Random
    • Random.raw_seedがシード以外にも利用できるようになったことでRandom.urandomにリネームされた(bug #9569
  • Socket
  • ConditionVariableQueueSizedQueueを高速化のため再実装したことでStructのサブクラスでなくなった(Feature #13552

Stdlibの互換性問題 (featureやbug修正を除く)

  • Gem化(Gemification)

    • 以下の標準ライブラリをデフォルトgemへ移行促進。
      • cmath
      • csv
      • date
      • dbm
      • etc
      • fcntl
      • fiddle
      • fileutils
      • gdbm
      • ipaddr
      • scanf
      • sdbm
      • stringio
      • strscan
      • webrick
      • zlib
  • Logger
    • Logger.new(“| command”)が意図せずコマンドを開いていた。現在は禁止され、Logger#initializeは仕様どおりString引数だけをファイル名として扱うようになった(bug #14212)。
  • Net::HTTP
    • Net::HTTP#startがデフォルトで:ENVp_addrに渡すようになった(bug #13351)。これを回避するには明示的にnilを渡す。
  • mathn.rb
  • Rubygems
    • ubygems.rbファイルをstdlibから削除(Ruby 1.9以降は不要)

C APIを更新

プラットフォームのサポート変更

実装の改善

  • Hashクラスのハッシュ関数がSipHash13に変更された(ユーザーからは見えないかもしれないが念のため)(Feature #13017
  • SecureRandomでOpenSSLよりもOS提供のソースが推奨されるようになった(bug #9569
  • ミューテックスを書き直してサイズ縮小&高速化(Feature #13517
  • lazyなProc割り当てによってブロックを用いたブロック渡しのパフォーマンスを向上(Feature #14045
  • traceインストラクションの代わりにTracePointフック用の動的instrumentationでオーバーヘッドを回避(Feature #14104
  • ERBのテンプレートからのコード生成がRuby 2.4の倍速くなった。

その他の変更

  • (experimental)STDERRがttyから変更されていない場合にバックトレースやエラーメッセージを逆順で出力(Feature #8661
  • (experimental)STDERRがttyから変更されていない場合にエラーメッセージをボールド/アンダーラインテキストで出力(Feature #14140
  • –with-ext設定オプションで引数が省略不可になった: たとえば./configure –with-ext=openssl,+を付けて実行するとOpenSSLライブラリをコンパイルすることを保証し、そうでない場合はビルドが異常終了する。

ただし引数の末尾に必ず,+を付けなければならないことに注意。これを指定しないとOpenSSLだけがビルドされる(Feature #13302

関連記事

Ruby 2.4.0がリリースされました!

Ruby 2.1.0リリース!注目の新機能を見てみましょう

Ruby 2.0.0リリース! – キーワード引数を使ってみよう

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ