Ruby 2.1には何が期待できますか?

数日前、Rubyコミュニティの重要人物の1人であるKonstantin Haaseが、Ruby 2.1のプレビューバージョンの発表に関するブログ投稿を投稿しました。 バージョン2.0と2.1の間の変更は、ロシア語でそのプレゼンテーションを読むのに十分なほど蓄積されています。

NB:もちろん、Ruby 2.1には以前のバージョン2.0の優れた機能がすべて含まれています。 以前のバージョンへの変更は言及されません。

精製メカニズム


改良メカニズムがRuby 2.0に導入されたことが知られています。 このメカニズムの実装は非常に物議をかもしました。そのため、バージョン2.0では、その機能は多少制限され、実験的とマークされました。

改良により、単一のRubyファイル内でおとりパッチを適用できることを思い出してください。

module Foo refine String do def foo self + "foo" end end end using Foo puts "bar".foo 

このファイルの外では、 Stringクラスのインスタンスはfooメソッドに応答しません。

Rubyの新バージョンでは、改良は実験的な機能ではありません。 さらに、上位レベルのスコープだけでなく、個々のモジュールにも適用できます。

 module Foo refine String do def foo self + "foo" end end end module Bar using Foo puts "bar".foo end 

過度に熱心に改良を加えると、非常に混乱したコードが作成される可能性があることに注意してください。 一部のRuby実装の開発者は、改良のサポートを拒否する可能性があるとすでに述べています。

10進リテラル


Rubyを使用する場合、小数の操作に精通している計算が実行されると、浮動小数点値が最適な方法で動作しないことに気付く場合があります。

 irb(main):001:0> 0.1 * 3 => 0.30000000000000004 

このような動作により、多数のRuby開発者が整数を使用し始め、結果を表示するときに指定された小数点以下の桁数をシミュレートします。 もちろん、この方法は厳密に指定された小数点以下の桁数でうまく機能します。 それ以外の場合、合理的な分数を使用する必要があります-これはそれほど悪くはありませんが、言語にはそれらを操作するのに十分な便利な構文がありません。

Rubyの新バージョンでは、小数および有理数を表す接尾辞rが導入されています。

 irb(main):001:0> 0.1r => (1/10) irb(main):002:0> 0.1r * 3 => (3/10) 

不変の文字列


コードに行宣言が含まれている場合、それを含むコード行が実行されるたびに、RubyはクラスString新しいオブジェクトを作成します。 これはラインの可変性によるものです。 このような場合、 キャラクターは一度だけ初期化されるため、はるかに効率的に動作します。 ただし、文字を文字列と比較するには、文字列を文字に、または文字を文字列に変換する必要があります。 このような変換の実行は、文字がガベージコレクション中に解放されず、文字を文字列に変換すると新しい行が作成されるため、DoS攻撃の可能性を開く危険な操作です。

この場合、否定的な結果から身を守る唯一の方法は、文字列を定数として保存して使用することです。

 class Foo BAR = "bar" def bar?(input) input == BAR end end 

多くの場合、可変性を取り除くために、ラインフリーズを実行します。 オブジェクトを凍結すると、Rubyコードの一部でオブジェクトが変更されなくなりますが、パフォーマンスは向上しません。

 class Foo BAR = "bar".freeze def bar?(input) input == BAR end end 

かなりばかげてかさばります。 幸いなことに、Ruby 2.1はこの問題を解決するための新しい構文を提供します。

 class Foo def bar?(input) input == "bar"f end end 

Stringクラスの不変オブジェクトは上記のコードで作成され、使用される場所はどこでも1回だけ初期化されます。

そのような構文は奇妙に見えるかもしれません。 同じコードフラグメントを同等に書き換えることができます。

 class Foo def bar?(input) input == %q{bar}f end end 

一般に、配列とハッシュに接尾辞fを適用する問題は未解決のままです。

必須のキー引数


何らかの理由で、Ruby 2.0の発表では、 必須のキー引数について言及されていませんでした。 そのため、Ruby 2.0では必要なキー引数が導入されています。

 def foo(a: 10) puts a end foo(a: 20) # 20 foo # 10 

メソッドを宣言するこのアプローチでは、デフォルトの引数値を指定する必要があります。 これは常に可能であるとは限らないため、Ruby 2.1では必要なキー引数を指定できます。

 def foo(a:) puts a end foo(a: 20) # 20 foo # ArgumentError: missing keyword: a 

メソッド宣言はメソッド名を返します


Rubyの以前のバージョンでは、 defを使用したメソッド宣言はnil返しました。

 def foo() end # => nil 

これで、この動作が変更され、メソッド名がシンボルとして返されます。

 def foo() end # => :foo 

これは、メタプログラミングやこのようなトリックの実行に役立ちます。 たとえば、 privateメソッドが引数を取ることができることを誰もが知っていますか?

 #     foo class Foo def foo end private :foo #  bar   def bar end end 

defが宣言されたメソッドの名前を返すので、メソッドを簡単にプライベートにできます。

 #     foo  bar class Foo private def foo end private \ def bar end def baz end end 

文字列から余分なバイトを削除する


Rubyには、文字列から余分なバイトを削除する便利な方法があります。

 some_string.scrub("") 

以前は、既存のすべてのRuby実装でこのようなメソッドの同じ動作を実現することは困難でした。そのため、このためのライブラリも利用できます。

StringScannerは名前付きキャプチャをサポートしています


多くの人は、標準言語ライブラリのStringScannerクラスが好きです。 特に、ルートパターンを解析するためにRailsで使用されます。 Sinatra 2.0も同じことを行います。

バージョン1.9は名前付きキャプチャのサポートを追加しましたが、 StringScannerはそれらをサポートしませんでした。

 require 'strscan' s = StringScanner.new("foo") s.scan(/(?<bar>.*)/) puts s[:bar] 

Ruby 2.0では、そのようなコードは例外をスローします。

 TypeError: no implicit conversion of Symbol into Integer 

しかし、Ruby 2.1で実行すると、すべてが正常になります。

 foo 

ネットワークインターフェイスを操作する


これで、 Socket.getifaddrsメソッドを使用してネットワークインターフェイスにアクセスできます。

 require 'socket' Socket.getifaddrs.each do |i| puts "#{i.name}: #{i.addr.ip_address}" if i.addr.ip? end 

そのようなプログラムの出力の例:

 lo0: fe80::1%lo0 lo0: 127.0.0.1 lo0: ::1 en0: fe80::1240:f3ff:fe7e:594e%en0 en0: 192.168.178.30 en2: fe80::3e07:54ff:fe6f:147a%en2 

タスクを計算するための数値を使用した迅速な作業


Ruby 2.1は、 Bignumクラスのオブジェクトの内部表現として128ビット整数を使用することにより、大きな数を扱う場合により高速です。 さらに、GNU Multiple Precision Arithmetic Libraryを使用すると、パフォーマンスがさらに向上します。

仮想マシンの変更


これで、Ruby仮想マシンは、グローバルメソッドキャッシュの使用とともに、関数呼び出しの場所でキャッシュを実行します 。 これについては別のスライドがあります。

RGenGC


Rubyの新しいバージョンは、新しい世代ベースのガベージコレクターを使用します。 これにより、ガベージコレクションが高速になります。 これに先立ち、「世界の停止-マーク-スイープ」スキームの下で動作する保守的なガベージコレクタが使用されました。

実際、古いコレクターは消えていません。 そのようなことは、内部および外部のRuby Cプログラミングインターフェイスの機能のために変更するのが困難です。

ただし、Ruby 2.1仮想マシンはオブジェクトをlightdarkに分類します。 割り当てられたクラスに応じて、ガベージコレクターの動作が決定されます。 明るいオブジェクトを暗くする操作があります。 たとえば、C言語の拡張機能から操作します。 開いているファイルなどのオブジェクトは、最初は暗いです。

新しいガベージコレクターは、 ライトオブジェクトでのみ機能します。

RubyGemsアップデート


RubyGemsはバージョン2.2.0のアップデートを受け取りました。これにより、いくつかのマイナーな改善がもたらされます。

永遠に続くものはない


最近のリリースは暫定版にすぎず、上記のすべてが変更される可能性があることを忘れないでください。

Source: https://habr.com/ru/post/J195844/


All Articles