Ruby 2.3の新機能

先週Ruby 2.3.0のプレビューがリリースされました 。 変更点の興味深い点:


安全なナビゲーションオペレーター


Rubyは、「?」に似た安全なナビゲーション演算子を導入しました。 Groovyおよび他のいくつかの言語で。 演算子は式を減らすために使用され、オブジェクトの存在がチェックされ、オブジェクトのメソッドは肯定的なチェックの場合にのみアクセスされます:

 obj.nil? && obj.some_method 

オブジェクトとメソッドのチェーンが使用される場合、チェックは面倒に見え、中間メソッドを数回無駄に実行する可能性があります。 たとえば、大きなプロファイル画像を安全に取得する典型的なRuby on Railsの場合:

 image = user && user.profile && user.profile.thumbnails && user.profile.thumbnails.large 

ここでは、 profileメソッドが3回実行され、 thumbnailsメソッドが2回実行されます。 最適化されたバージョンはさらに複雑になります。

 image = user && (profile = user.profile) && (thumbnails = profile.thumbnails) && thumbnails.large 

同時に、結果が完全に正しくない場合があります。より深く内側に移動するオブジェクトの1つが存在しない場合、イメージはnilではなくfalseになりfalse 。 そして、 nil?をチェックしたらnil? 、コードはさらに複雑になります。

また、チェックせずにチェーンの奥深くに移動する方法もあります。たとえば、通常の方法で例外をキャッチします。

 image = begin user.profile.thumbnails.large rescue NoMethodError nil end 

または接尾辞レスキューの不承認:

 image = user.profile.thumbnails.large rescue nil 

ActiveSupportは、この問題を解決するためのtryおよびtry!メソッドを提供しますtry!

 image = user.try(:profile).try(:thumbnails).try(:large) 

これらのメソッドはObjectクラスに追加され、呼び出されたときに最初に呼び出されたメソッドの存在を確認し、存在しない場合はnilを返します。 user#profileメソッドを持っている場合、それが実行され、 try(:thumbnails)がチェーンのさらに下で呼び出されます。 usernil場合、 #trynilを返すため、チェーン#tryはさらに2回nilで呼び出されます。 ゆっくり? しかし、簡単に。

Rubyで新しい安全なナビゲーション演算子を作成する理由


タスク#11537では 、Ruby 2.3.0での安全なナビゲーションのために、演算子「。?」 最初に追加され、後に「&。」に変更されました。 新しい構文では、例の式は次のように記述できます。

 image = user&.profile&.thumbnails&.large 

簡潔な外観とともに、このような実装はnilクイックチェックを提供します。これは、変更がパーサーレベルで実装され、Rubyコードがチェックに関与しないためです。 nilと、チェーンのさらなる実行が中断されます。 チェックは論理条件ではなくnilで実行されるため、結果がfalse場合、実行はチェーンに沿ってさらに正常に続行されます。

引数がメソッドに渡される場合、 tryとは異なり、オブジェクトが存在し、メソッドが実際に呼び出された場合にのみ引数が評価されます。 たとえば、ActiveSupportの場合、式obj.try(:foo, bar())は、 objが存在しない場合でも常にbar()実行しbar() 。 ただし、式obj&.foo(bar())では、引数bar()ojb nil ojbない場合にのみ評価されます。

安全なナビゲーションは、属性に値を割り当てるときにも使用できます。

 obj&.attr += 1 

機能のリクエストが表示されてから最初の実装オプションで確認およびコミットされるまで、わずか1か月以上かかりました。

#digを使用して、ネストされたハッシュと配列に深くナビゲートします。


機能#11688は、 HashArray digメソッドを追加します。これは、ネストされたハッシュと配列から安全に値を取得するために使用されます。 このメソッドは式を置き換えます。

 value = hash[:a].nil? ? nil : hash[:a][:b].nil? ? nil : hash[:a][:b][:c] 

または:

 value = hash[:a][:b][:c] rescue nil 

に:

 value = hash.dig(:a, :b, :c) 

ネストされたハッシュと配列へのアクセスは、Railsアプリケーションが受信したHTTPリクエストのパラメーターを処理するとき、またはYAMLまたはJSON構造を操作するときによく使用されます。 digを追加すると、便利なアクセス方法が提供されるだけでなく、数十倍も高速化されます。

digメソッドも最近Structに追加されましたが、最初のプレビュー2.3.0には到達できませんでした。

ライン不変性


Ruby 3では、すべての文字列リテラルは不変です。 不変性をめぐる紛争は長い間続いており、現在ではこの方向への動きがより具体的になっています。 これは、デフォルトですべての文字列リテラルの不変性を可能にする「マジック」コメントfrozen-string-literalの外観で表され、さらに--enable/--disable=frozen-string-literalこの動作を制御します。

不変の文字列を支持する主な議論は、内部最適化による速度の向上です。 ほとんどの場合、ライフサイクル全体を通して行は変更されないままであり、この動作を修正すると、コードを変更せずにパフォーマンスを改善できます。

そして、私たちは小さな投票をしています


Jet9コンテナでRubyアプリケーションをホストする準備を整えました。 クラウドホスティングフェールオーバークラスターの両方。

RubyがJet9に最初に登場する理由の1つは、自社の内部サービスと顧客の内部サービス(サイト、請求、ドキュメント管理、バグトラッカー、チケットなど)のメンテナンスを統合することです。 私たちの生活を簡素化し、異なるディストリビューション、異なる構成のHAクラスター、および個々の物理サーバーから動物園を更新および維持するコストを削減するために、Jet9プラットフォーム上のいくつかの典型的なHAクラスターにすべてを転送します。 それらのほとんどはRubyで書かれています-彼らは独自のアプリケーションとサードパーティのアプリケーション(Redmine、Gitlab)を使用しています。 そのため、Jet9でRubyをサポートしました(自分自身を含む)。また、自分でテストします。

アプリケーションはNginx + Apache + mod_passenger(5.0.21)の下で実行され、これが最も便利な方法です。 ただし、スタンドアロンのPassengerまたは他のアプリケーションサーバー(Unicorn、Puma)を使用できます。 バージョン2.2.2および2.2.3が利用可能になり、他のバージョンも準備中です。 この点に関して、調査は次のことを行います。

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


All Articles