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のアップデートを受け取りました。これにより、いくつかのマイナーな改善がもたらされます。



永遠に続くものはない



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



All Articles