ルールエンジンでRubyコードで書かれたルールを評価する方法として、eval()
を使用するアプリケーションでメンテナンスを継承しました。 ロット他の方法がありますが、これまでのコードベースは非常に大きく、それを何か他のものに変更することは、この時点では非常に時間がかかるでしょう。今のところ私はeval()
を使用して立ち往生していると仮定します。Rubyのevalと「既に初期化された定数」を回避するにはどうすればよいですか?
通常、書き込まれたルールは、データベースから同じオブジェクトの一部を呼び出し、ルールライターは、ルール内の変数に互いに同じ名前を付けます。これは、開発中にコンソール内のページやページに「既に初期化された定数」の警告を表示します。 は、DEV環境でのプログラムの実行速度を遅くしているもののようを感じている場合は、
まず、それがで大きなパフォーマンスヒットだ場合ので、私は思ったんだけど:
私はカップルの事を思ったんだけどプロダクション環境、具体的には、私が知っているeval()
自体ではなく、それらの警告がポップであることがヒットしています。
第2に、各ルールの実行を「ネームスペース」する方法はありますか。そのため、要求内の他のすべてのエバリュと同じスコープでその変数を定義していないため、私は||=
構文を使用するか、名前がすでに定義されているかどうかを確認するためにすべてのルールを書き直すことができると知っていますが、可能であればeval()
を実行するコードからやっています。
**例ルールで更新** 質問には、ユーザーに表示するタイミングに関する規則があります。たとえば、ユーザーがアパートに住んでいると述べた場合は、アパートメントの大きさを確認するために別の質問を表示する必要があります。
UserLivesInApartment = Question.find_by_name "UserLivesInApartment"
UserLivesInApartment.answer_for(current_user)
評価に先立っ範囲でCURRENT_USER変数がありますが保証はevalを呼び出すコード:だから2番目の質問のrule_textは、次のようになります。
サンプルとサンプルコードを見るのに役立ちます。つまり、これは主観的な質問であり、助けの能力を弱めるコードを推測する必要があります。 –
これはちょうど正しいルビーではなく、警告を正しく生成するはずです。なぜあなたは変数に定数を代入しますか?コードをリファクタリングして、クラス変数@user_lives_in_apartmentまたは単純な変数user_lives_in_apartmentにする必要があると思います。それ以外の場合は、アクティブなレコード照会の結果でグローバル名前空間を汚染します。 – sunkencity
これは、私が継承したシステム内の数百のルールの1つの例です。あなたが提案しているリファクタリングを行う最もクリーンな方法は何ですか? – Paul