Rails Hidden Gems:ActiveSupport StringInquirer
Railsは大きなフレームワークであり、毎年大きくなります。これにより、いくつかの便利な機能が見過ごされやすくなります。このシリーズでは、特定のタスクのためにRailsに組み込まれているあまり知られていない機能をいくつか見ていきます。
このシリーズの最初の記事では、Rails.env.test?
を呼び出す方法を見ていきます。 あまり知られていないStringInquirer
を使用することで、実際には内部で機能します ActiveSupportのクラス。さらに一歩進んで、StringInquirer
についても説明します。 それがどのように機能するかを確認するためのソースコード。これは(ネタバレ注意)特別なmethod_missing
を介したRubyのメタプログラミングの簡単な例です。 メソッド。
Rails.envヘルパー
Rails環境をチェックするコードを見たことがあるでしょう:
if Rails.env.test?
# return hard-coded value...
else
# contact external API...
end
ただし、test?
実際にそうです、そしてこの方法はどこから来たのですか?
Rails.env
をチェックすると コンソールでは、文字列のように機能します:
=> Rails.env
"development"
ここでの文字列は、RAILS*ENV環境変数が設定されているものです。ただし、文字列だけではありません。コンソールでクラスを読むと、次のように表示されます。
=> Rails.env.class
ActiveSupport::StringInquirer
Rails.env
実際にはStringInquirerです。
StringInquirer
StringInquirerのコードは簡潔で、十分に文書化されています。ただし、Rubyのメタプログラミング機能に精通していない限り、どのように機能するかは明らかではないかもしれません。ここで何が起こっているのかを見ていきます。
class StringInquirer < String
...
end
まず、StringInquirerがStringのサブクラスであることがわかります。これがRails.env
の理由です 呼び出すと文字列のように機能します。 Stringから継承することで、Stringに似た機能がすべて自動的に取得されるため、Stringのように扱うことができます。 Rails.env.upcase
ActiveRecordModel.find_by(string_column: Rails.env)
と同様に機能します 。
Rails.env
はStringInquirerの便利な組み込みの例であり、独自の例を自由に作成することもできます:
def type
result = "old"
result = "new" if @new
ActiveSupport::StringInquirer.new(result)
end
次に、戻り値に疑問符のメソッドを取得します。
=> @new = false
=> type.old?
true
=> type.new?
false
=> type.testvalue?
false
=> @new = true
=> type.new?
true
=> type.old?
false
method_missing
method_missing
ここの本当の秘密のソースです。 Rubyでは、オブジェクトのメソッドを呼び出すたびに、Rubyは、メソッドのオブジェクトのすべての祖先(つまり、基本クラスまたは含まれているモジュール)を調べることから始めます。見つからない場合、Rubyはmethod_missing
を呼び出します 、探しているメソッドの名前と引数を渡します。
デフォルトでは、このメソッドは例外を発生させるだけです。私たちはおそらく、NoMethodError: undefined method 'test' for nil:NilClass
に精通しているでしょう。 エラーメッセージの種類。独自のmethod_missing
を実装できます これは例外を発生させません。これはまさにStringInquirer
です。 する:
def method_missing(method_name, *arguments)
if method_name.end_with?("?")
self == method_name[0..-2]
else
super
end
end
任意の場合 ?
で終わるメソッド名 、self
の値を確認します (つまり、文字列)?
のないメソッド名に対して 。言い換えると、StringInquirer.new("test").long_test_method_name?
を呼び出す場合 、戻り値は"test" == "long_test_method_name"
です。 。
メソッド名がない場合 疑問符で終わると、元のmethod_missing
にフォールバックします (例外を発生させるもの)
Respond_to_missing?
ファイルにはもう1つのメソッドがあります:respond_to_missing?
。これはmethod_missing
のコンパニオンメソッドであると言えます。 。 method_missing
機能を提供します。また、これらの疑問符の終了方法を受け入れることをRubyに通知する方法も必要です。
def respond_to_missing?(method_name, include_private = false)
method_name.end_with?("?") || super
end
これは、respond_to?
を呼び出すと機能します。 このオブジェクトに。これがないと、StringInquirer.new("test").respond_to?(:test?)
を呼び出した場合 、結果はfalse
になります test?
という明示的なメソッドがないためです。 。 Rails.env.respond_to?(:test?)
を呼び出すとtrueが返されると予想されるため、これは明らかに誤解を招く恐れがあります。 。
respond_to_missing?
これが、Rubyに「はい、そのメソッドを処理できます」と言える理由です。メソッド名が疑問符で終わっていない場合は、スーパークラスメソッドにフォールバックします。
方法がわかったので StringInquirerは機能します。それが役立つ可能性のあるインスタンスを見てみましょう:
1。環境変数
環境変数は、StringInquirerに最適な2つの基準を満たしています。まず、多くの場合、可能な値の限られた既知のセット(enum
など)があります。 )、そして次に、それらの値に依存する条件付きロジックがあることがよくあります。
アプリが支払いAPIに接続されており、環境変数にクレデンシャルが保存されているとします。本番システムでは、これは明らかに実際のAPIですが、ステージングバージョンまたは開発バージョンでは、サンドボックスAPIを使用します。
# ENV["PAYMENT_API_MODE"] = sandbox/production
class PaymentGateway
def api_mode
# We use ENV.fetch because we want to raise if the value is missing
@api_mode ||= ENV.fetch("PAYMENT_API_MODE").inquiry
end
def api_url
# Pro-tip: We *only* use production if MODE == 'production', and default
# to sandbox if the value is anything else, this prevents us using production
# values if the value is mistyped or incorrect
if api_mode.production?
PRODUCTION_URL
else
SANDBOX_URL
end
end
end
上記では、ActiveSupportのString#inquiry
を使用していることに注意してください 文字列をStringInquirerに簡単に変換するメソッド。
2。 APIレスポンス
上記の支払いAPIの例を続けると、APIは成功/失敗の状態を含む応答を送信します。繰り返しになりますが、これはStringInquirerの候補となる2つの基準を満たしています。可能な値の限定されたセットと、これらの値をテストする条件付きロジックです。
class PaymentGateway
def create_charge
response = JSON.parse(api_call(...))
result = response["result"].inquiry
if result.success?
...
else
...
end
# result still acts like a string
Rails.logger.info("Payment result was: #{result}")
end
end
StringInquirerはあなたの後ろポケットに入れるのに面白いツールですが、個人的にはあまり頻繁に手を伸ばすことはありません。いくつかの用途がありますが、ほとんどの場合、オブジェクトの明示的なメソッドは同じ結果をもたらします。明示的に名前が付けられたメソッドにもいくつかの利点があります。値を変更する必要がある場合は、1つの場所を更新するだけで済みます。および 開発者がメソッドを見つけようとしている場合、コードベースを簡単に検索できます。
StringInquirerに焦点を当てていますが、この記事は、method_missing
を使用したRubyのメタプログラミング機能のいくつかをより穏やかに紹介することを目的としています。 。おそらくmethod_missing
は使いたくないと思います アプリケーションで。ただし、Railsやgemが提供するドメイン固有言語などのフレームワークでよく使用されるため、問題が発生したときに「ソーセージがどのように作られるか」を知ることは非常に役立ちます。
-
Google Play ストアの 2022 年ベスト ヒドゥン ジェムズ
Google Play ストアには、ゲーム、ソーシャル アプリ、最適化、バッテリー セーバー アプリなど、各カテゴリに数百万のアプリがあります。他のアプリほど人気がないアプリは他にもたくさんありますが、それらは仕事を成し遂げるのに本当に役立ち、頻繁に使用するのが大好きです.隔年と同様に、Google Play ストアは 2022 年に隠れた宝石カテゴリでチャートを突破したアプリをリストしました。 そこで今日は、2022 年の最高の隠れた宝石カテゴリで、受賞歴のある Android アプリのトップ 5 を共有します。 ソクラティック – 数学の答えと宿題のヘルプ Socratic は
-
知っておくべきWindows 11のヒントと隠された宝石
Windows 11 は、互換性のあるデバイスの無料アップグレードとして利用でき、多くの新機能と改善が含まれています。新しく再設計されたスタート メニュー タスクバー、Andriod アプリをサポートする改良された Microsoft ストア、統合された Microsoft チーム、スナップ レイアウト、ウィジェットなどがあります。しかし、レドモンドの巨人によって公式に発表された大きなニュースと機能に加えて、Windows 11 には多くの小さな変更が含まれており、一見すると明らかではないかもしれません。この投稿では、Windows 11 の非表示の機能をいくつか紹介しました。 について知って