Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Ruby 2.4の注目すべき9つの新機能まとめ

新しいRubyのバージョンがクリスマスにリリースされるのは、もはや恒例行事となっています。

この記事では、Ruby 2.4の特に興味深い変更点をいくつかピックアップしてご紹介します。最新情報のキャッチアップにぜひお役立てください。

キーワード引数に対応したFloat#round

アプリケーションで浮動小数点数を扱っているなら、丸め処理にはfloorceilを使うことをおすすめします。Ruby 2.4では、Float#roundメソッドのデフォルトの挙動が変更されるからです。

:

# Ruby 2.3
(2.5).round
3

# Ruby 2.4
(2.5).round
2

デフォルトの挙動は「偶数への丸め(round-to-nearest-even)」に変更される予定でした。

更新: Ruby 2.4の正式版では、Float#roundのデフォルト挙動は「四捨五入」に戻されました。この記事の公開後にMatzが判断を下したものです。

さらに、Float#roundは引数を受け取るようになり、丸めの方式を指定できるようになりました。

選択できるオプションは以下の通りです:

  • :even(偶数への丸め)
  • :up(切り上げ)
  • :down(切り捨て)

:

(4.5).round(half: :up)
5

また、Float#floorFloat#ceilFloat#truncateも、精度を指定できるオプション引数を受け取るようになりました。

IOメソッドのchompフラグ

getseach_lineのようなメソッドを使ったことがあれば、あの厄介な改行文字の処理に悩まされた経験があるはずです。

こんな感じのやつです: \n

初心者がつまずきがちなポイントですが、この新機能が助けになるかもしれません!

例を見てみましょう:

input = gets.chomp
# "abc\n"

Ruby 2.4では、chompキーワード引数を指定することで、getsが自動的に改行文字を取り除いてくれます。

:

input = gets(chomp: true)
# "abc"

これはfalsenil(Rubyにおける唯一の「偽」と評価される値)以外の任意の値で機能します。

そのため、次のような書き方も動作します(混乱を招く可能性があるため推奨はされません):

input = gets(chomp: 1234)
# "abc"

大した機能ではありませんが、メソッド呼び出しを1回節約できますね。

Pathname#empty?

Ruby 2.4では、Dir#empty?File#empty?が実装されました。これらのメソッドを使うと、ディレクトリやファイルが空かどうかをチェックできます(そのままの意味ですね)。

さらに、Pathname#empty?も最近追加されました。

Pathnameをご存じない方のために簡単に説明すると、DirクラスとFileクラスの機能を統合したクラスです。

また、文字列の代わりにPathnameオブジェクトを返すという点で、より「オブジェクト指向的」でもあります。

:

Pathname.empty?("file or directory name")

コミット: https://github.com/ruby/ruby/commit/9373c5efb993dd8cae0526118805449b19af2c22

Setのcompare_by_identity

Set(集合)は標準ライブラリの一部として提供されているデータ構造で、重複のない要素のコレクションを管理するのに役立ちます。

デフォルトでは、オブジェクトは値に基づいて比較されます(より正確には、ハッシュ値に基づきます)。

しかしRuby 2.4では、オブジェクトIDに基づいて一意なオブジェクトのセットを持つことが可能になりました。

:

require 'set'

# 通常のセット

set = Set.new

set << 123 << 123 << "abc" << "abc"
# [123, "abc"]

# 同一性ベースのセット

set = Set.new().compare_by_identity

set << 123 << 123 << "abc" << "abc"
# [123, "abc", "abc"]

この機能の興味深い使い方をご存じの方は、ぜひコメントで教えてください。

コミット: https://github.com/ruby/ruby/commit/76977611dd68e384fdce8c546efda5e1931e67a6

Kernel#send、BasicObject#__send__、Symbol#to_procでのRefinements

ここでrefinementsについて詳しく解説するつもりはありませんが、基本的な考え方は、Stringのようなクラスにメソッドを追加しつつ、その変更を1つのファイルやクラスの範囲に「局所化」できるというものです。

Ruby 2.4からは、refinementsで定義されたメソッドが、Kernel#sendSymbol#to_procなどのメソッド経由で呼び出された場合にも利用できるようになりました。

:

module TenTimes
  refine String do
    def ten_times
      puts self * 10
    end
  end
end

class Thing
  using TenTimes

  "abc".send(:ten_times)
end

2.3以前でこれを試すと、「undefined method」エラーが発生します。

コミット: https://github.com/ruby/ruby/commit/35a29390197750abf97ef16fa0740e377764daef

Hash#transform_values

Railsから抽出され、Ruby本体に直接取り込まれたもう一つのメソッドがこちらです。Hash#transform_valuesは、Array#mapと似たような動作をします。

:

h = {a: 1, b: 2, c: 3}

h.transform_values { |v| v * 10 }
# {a: 10, b: 20, c: 30}

破壊的な変更が必要な場合に備えて、Hash#transform_values!も用意されています。

Kernel#cloneがオプションのキーワード引数を受け取るように

ご存じのとおり、Rubyのオブジェクトはコピーすることができます。Rubyのオブジェクトの多くはミュータブル(変更可能)なので、元のオブジェクトへの意図しない変更を避けたい場合に便利です。

オブジェクトをコピーするためのメソッドは2つあります:

  • clone
  • dup

cloneとdupにはいくつかの細かい違いがありますが、この記事では「cloneは元のオブジェクトの凍結(frozen)状態を保持するが、dupは保持しない」という点だけ押さえておきましょう。

2.4の新機能として、「freeze」フラグを付けてcloneを呼び出せるようになりました。

:

foo = "test".freeze
boo = foo.clone(freeze: false)

boo.frozen?
# false

これがどの程度実用的なのかは分かりませんが、選択肢が増えることに異を唱える人はいませんよね。

コミット: https://github.com/ruby/ruby/commit/320ae01c5fb091eab0926c186f304a9caeda1ace

Thread.report_on_exception

2.4で登場するもう一つの機能がThread.report_on_exceptionです。これは、スレッド内の例外がデフォルトではサイレントに無視され、コードの問題が隠れてしまう可能性があることが理由で提案されました。

デフォルト値はfalseですが、アプリケーションでスレッドを使用している場合は、Ruby 2.4へのアップグレード時にこの機能を有効にしてみることをおすすめします。

:

Thread.report_on_exception = true

t1 = Thread.new do
  puts  "In new thread"
  raise "Exception from thread"
end

sleep(1)
puts "In the main thread"

これにより例外が表示されますが、プログラムがクラッシュすることはありません。代わりの選択肢として、以前から利用できるThread.abort_on_exceptionもあります。

なお、このメソッドにはインスタンス版も存在するため、すべてのスレッドではなく、スレッドごとに個別にこのオプションを設定することも可能です。

Binding#irb

デバッグにbinding.pryを使うのがお好きですか?実は、似たような動作をするbinding.irbも使えるようになりました。

ただしirbベースなので、pryが提供するシンタックスハイライトのような便利な機能はまだ利用できません。

とはいえ、何らかの理由でpryが使えない環境では、ないよりはずっとましですね。

コミット: https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a

まとめ

この新しいRubyのバージョンには、興味深い機能が数多く盛り込まれています。リリースされたらぜひ実際に試してみてください。

Ruby 2.4の新機能をより多くの人に知ってもらうために、この記事のシェアもお忘れなく!


  1. Ruby 2.6の新機能9選|コード例でわかる注目ポイントを徹底解説

    Ruby 2.6には、開発者の生産性を高める新しい機能やパフォーマンス改善が多数盛り込まれています。 本記事では、Ruby 2.6で導入された9つの注目新機能を、実際のコード例とともにわかりやすく紹介します。最新のRuby動向をキャッチアップしたい方は、ぜひ最後までご覧ください。 1. 無限Range(Endless Range) Ruby 2.5以前でもFloat::INFINITYを使えば終端のない範囲を表現できましたが、Ruby 2.6ではさらに直感的な記法が使えるようになりました。 新しい無限Rangeは次のように書きます。 (1..) 通常のRangeが(1..10)のように終端

  2. Windows 8.1 Update 1の新機能徹底解説|タスクバー・マウス操作・起動設定の変更点

    Microsoftは、4月8日に配信開始されるWindows 8.1 Update 1の詳細を発表しました。主な新機能として、タスクバーの強化、スマートなマウス操作の調整、そしてマウスとキーボードユーザーに配慮したスタート画面の改良などが含まれています。 第1部:Windows 8.1の主要アップデート内容 1. タスクバーへのModernアプリの表示 Windowsストアアプリ(Modernアプリ)をデスクトップのタスクバーにピン留めできるようになりました。長年Windowsを使い続けてきたユーザーの間では賛否が分かれるかもしれませんが、これはタブレット向けのストアアプリをデスクトップ