先週
Ruby 2.3.0のプレビューがリリースされました 。 変更点の興味深い点:
- オブジェクトの深い安全なナビゲーション演算子(安全なナビゲーション演算子)、 #11537
- より深いネストされたハッシュまたは配列にアクセスするために、ハッシュと配列に
dig
メソッドが追加されました#11688 - デフォルトで固定文字列リテラルへの移動( 正当化 、議論#11473
安全なナビゲーションオペレーター
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)
がチェーンのさらに下で呼び出されます。
user
が
nil
場合、
#try
は
nil
を返すため、チェーン
#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は、
Hash
と
Array
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が利用可能になり、他のバージョンも準備中です。 この点に関して、調査は次のことを行います。