0

コードをリファクタリングする方法を考える必要があります:

attr_accessor :product
attr_reader :name, :mark

def name=(value)
  super unless product.present?
end

def mark=(value)
  super unless product.present?
end

... and a whole bunch of method of sorts.

アイデアは単純です - 製品が既に設定されている場合、値の割り当てを拒否します。しかし、上記のコードはまったく DRY ではありません。

何か案は?

4

2 に答える 2

2
attr_accessor :product
attr_reader :name, :mark

["name", "mark"].each do |method|
 define_method("#{method}=") do |value|
  super(value) unless product.present?
 end
end
于 2013-10-22T22:08:12.913 に答える
1

これを処理するようなメソッドを作成できますattr_*。これを行うには、クラスを再度開きClass、次のメソッドを定義します。

def attr_validator(*args)

  #We simply iterate through each passed in argument...
  args.each do |arg|

    # Create an attr_reader
    self.class_eval("
      def #{arg};
        @#{arg};
      end
    ")

    # Here we hardcode "product" since this every attribute
    # checks itself against this object
    self.class_eval("
      def #{arg}=(val);
        super unless product.present?;
      end
    ")                      

  end
end

このようにして、プリプロセッサ メソッド (私の場合はattr_validator) に属性を追加する冗長性と、メタプログラミング用の別の配列を取り除きます。

これはこんな風に使える...

attr_accessor :product
attr_validator :name, :mark, :price, :stock # ...and so on
于 2013-10-22T22:41:20.937 に答える