私は、APIを定義する複数の抽象クラスと属性のメソッドを提供するサブクラスを持つ特定の実装を持つプラグインスタイルのアーキテクチャを持つアプリケーションで作業しています抽象クラスで定義されています。 Connection、Table、Columnなどの抽象クラスと、特定のデータベースに対するこれらの特定のサブクラスを持つ汎用データベースアダプタを考えてみましょう。クラスレベルの動的メソッド作成をルビのモジュールに移す
DRYを試みるために、各抽象クラスの属性(デフォルト値)をATTRIBUTES
というクラス定数配列として宣言します。 Rubyは真の抽象クラスをサポートしていないので、抽象クラスで呼び出された場合に例外を発生させるメソッドを動的に作成します。たとえば、次のように
module MyApplication
class Operation
ATTRIBUTES = { name: '', parameters: [], type: :void }
ATTRIBUTES.keys.each do |a|
str = "Method '%s' called on abstract 'MyApplication::Operation' class"
define_method(a) { raise (str % a) }
define_method("#{a}=") { |x| raise (str % "#{a}=") }
end
end
end
Iハードコードそれが抽象Operation
クラスのサブクラスであるかもしれない、と私はメッセージにしたいので、私は、現在のクラスの名前を使用することはできませんので、メッセージ内のクラス名呼び出されているメソッドが抽象クラスにあることを明示してください。
私はこれらの抽象クラスをいくつも持っています。これらのスタブメソッドを作成するために、ほとんど同じコードをコピーしました(属性リストとクラス名だけが異なります)。私は、この抽象クラスからインクルード(または拡張)できるモジュールにこのコードを組み込むためのさまざまな方法を試しましたが、私の脳はここで折り畳まれ、メタプログラミングの詳細を整理しようとしています働く:)
同じコードを何度も何度も繰り返さないようにするために、この共通のクラスレベル(インスタンス作成のメソッド)コードをモジュールに取り込む人はいますか?
これはそれらすべてが終わるすべてのクラスで定義されているになるだろうこれは、*モジュール*にスタブメソッドを追加しませんPluginHelpersを拡張しますか?私は、この作業が望ましくない副作用を持つようになったという試みの(多くの)反復の1つのように感じます。 –
私はあなたの懸念を理解していますか分かりません。私が書いたコードをとり、あなたの特定のユースケースのために試してみよう。 –
私はそれを動作させるのに苦労していましたが、それはパスと 'require'に問題があることが判明しました。今働いているようですので、助けてくれてありがとう! –