2017-09-22 2 views
0

Rubyで異なるValueオブジェクトを表すためのコードは次のとおりです。異なるクラス間で変更されるのは、値オブジェクトの属性のリストを表すINITIALIZATION_ATTRIBUTES配列だけです。私はこのコードをDRYする方法を見つけることができません。私はモジュールを使い、クラスの定数にアクセスしようとしましたが、hereという奇妙なConstantルックアップの振る舞いがあります。基本的に、Moduleコードは複数回評価され、最後に評価されたクラスの定数を解釈し、その値をすべてのValue Objectクラスに適用します。Rubyでこのコードを実行するには

もっと良い選択肢はありますか?私もベースクラスで試しましたが、動作させることができませんでした。

module Values 
    class MaintenanceRegimeSerializer 
     INITIALIZATION_ATTRIBUTES = [:distance_between_services, :months_between_services] 

     def self.load(json) 
     json ||= '{}' 
     hash = JSON.parse json, symbolize_names: true 
     self.new(*INITIALIZATION_ATTRIBUTES.map {|key| hash[key]}) 
     end 

     def self.dump(obj) 
     unless obj.is_a?(self) 
      raise ::ActiveRecord::SerializationTypeMismatch, 
      "Attribute was supposed to be a #{self}, but was a #{obj.class}. -- #{obj.inspect}" 
     end 

     obj.to_json 
     end 

     attr_reader *INITIALIZATION_ATTRIBUTES 

     define_method :initialize do |*args| 
     raise ArgumentError unless INITIALIZATION_ATTRIBUTES.length == args.length 
     INITIALIZATION_ATTRIBUTES.each_with_index do |attribute, index| 
      instance_variable_set "@#{attribute}", args[index] 
     end 
     end  

    end 
    end 
+0

初期化属性を除いて、いくつかのクラスがあり、それらはすべて同じですか? – EJ2015

+0

あなたは、あなたがどこかで繰り返していることを暗示して、このコードをよりドライにしたいとします。それはどこにありますか?これは私にとってかなり「メタ」に見えます。 –

答えて

1

これは、2つのモジュールを重ねることによって実行できます。外部モジュールは、内部モジュールを初期化する機能を提供します。クラス属性はすべてのクラスを含むすべてのクラスで一意であるため、クラスの属性を含むクラス属性はクラス属性を含む別のクラス属性と競合できません。

関連する問題