定義? RubyおよびRailsのメソッド
-
04-07-2019 - |
質問
ERBの上に書かれた非常に古いテンプレートシステムがあります。データベースに保存されているERBテンプレートに依存しています。それらは読み取られてレンダリングされます。あるテンプレートから別のテンプレートにデータを渡したい場合は、:localsパラメーターをRailsのrenderメソッドに使用します。一部のテンプレートでこれらの変数のデフォルト変数を設定するには、定義済みを使用しますか?ローカル変数が定義されているかどうかを単純に通知するメソッド。そうでない場合は、次のようにデフォルト値で初期化します。
unless defined?(perex)
perex = true
end
アプリを最新のRailsにアップグレードしていますが、奇妙な動作が見られます。基本的に、これは時々機能する場合があり(perexが未定義である場合もあります)、そうでない場合もあります(perexが定義され、nilに設定されます)。これは、他に何も変更することなく起こります。
2つの質問があります。 定義を使用する以外のより良い方法はありますか?信頼性の低いものはどれですか(トップRails 1.6では数年間信頼性がありました)?このような方法では、すべてのテンプレートを書き換える必要はありません。 私はRubyのドキュメントを調べてきましたが、定義について何も見つかりませんでしたか?方法。廃止されたのですか、それとも単なる盲目ですか?
編集:実際の問題は、Ruby / eRBのバグと思われるものが原因でした。場合によっては unless ステートメントが機能することもありますが、機能しないこともあります。奇妙なことは、たとえ2番目の行が実行されたとしても、残りの世界では perex がゼロのままであるということです。定義を削除しますか?解決しました。
解決
最初:実際には、 defined?
は演算子。
2番目:あなたの質問を正しく理解している場合、その方法はこのRubyのイディオムを使用することです:
perex ||= true
perex
が未定義または nil
の場合、trueを割り当てます。あなたの例は値が nil
の場合に割り当てを評価しないので、あなたの例がすることは正確ではありませんが、それを信頼しているなら、私の意見では、それを見ずに、あなたはそうではありません明確なコードを記述します。
編集:Honzaが述べたように、上記のステートメントは false
の場合、 perex
の値を置き換えます。次に、最小行数を書き換えるために以下を提案します。
perex ||= perex.nil? # Assign true only when perex is undefined or nil
他のヒント
ローカルがRailsテンプレートで定義されているかどうかをテストする最も安全な方法は次のとおりです。
local_assigns[:perex]
これは、 defined?
は実装制限のため使用できないという説明とともに、Rails APIに文書化されています。
mislavの答えに従って、私はRails APIでそのドキュメントを探しに行き、 Class ActionView :: Base (見出し「"ローカルテンプレートをサブテンプレートに渡す"」の下)。しかし、mislavがやった以上のことはほとんど言わなかったので、検索する価値はほとんどありませんでした。このパターンが推奨されていることを除いて:
if local_assigns.has_key? :perex
考慮事項g mislavの元の回答および KenBの詳細では、以下が絶対的な最良のアプローチであると思います(ただし、私は意見を受け入れています)。 Rubyの Hash#fetch を利用しますキーが元のハッシュに存在しない場合に代替値にフォールバックするメソッド。
perex = local_assigns.fetch(:perex, true)
これは、 false
値を許可する場合があるため、ほとんどのユーザーが提案する || =
メソッドよりも優れています。たとえば、次のコードでは、 false
の値を決して渡せません:
perex = local_assigns[:perex] || true