DRY (Don't Repeat Yoursel) の意味を勘違いしてたかも

なんか、DRY の原則をすっげー勘違いしてたかも。

The DRY (Don't Repeat Yourself) Principle states:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

http://c2.com/cgi/wiki?DontRepeatYourself


DRY (Don't Repeat Yourself) っていうから、単に「同じことを繰り返さない」という意味だと思っていた。だから、たとえば

class Node
end
class Element < Node
  def accept(visitor)
    visitor.visit_element(self)
  end
end
class Text < Node
  def accept(visitor)
    visitor.visit_text(self)
  end
end

となっているのは DRY じゃないから

class Node
end
class Element < Node
end
class Text < Node
end

def acceptor(*klasses)
  klasses.each do |klass|
    name = ActiveSupport::Inflector.underscore(klass.name)
    klass.class_eval <<-END
      def accept(visitor)
        visitor.visit_#{name}(self)
      end
    END
  end
end

acceptor Element, Text

とすれば DRY になる、と思ってたんだけど、そういうもんでもないらしい。

Notes: This principle is similar to OnceAndOnlyOnce, but with a different objective. With OnceAndOnlyOnce, you are encouraged to refactor to eliminate duplicated code and functionality. With DRY, you try to identify the single, definitive source of every piece of knowledge used in your system, and then use that source to generate applicable instances of that knowledge (code, documentation, tests, etc).

http://c2.com/cgi/wiki?DontRepeatYourself


なんかねー、コードの重複をなくすのが DRY ということじゃなくて、情報の重複をなくすのが DRY の本当の意味らしい。コードの重複をなくすのは Once and Only Once という原則であって、DRY とはまたちょっと違うそうだ。

だからたとえば、ActiveRecord が DB スキーマから情報をとってきてモデルクラスを自動設定するのは、まさに情報の重複をなくしているから、DRY といえる。
しかし上のコードのように、単にコードの重複をなくしただけなのは DRY とはいわないみたいなんだよね*1


さあ困った。どうすっべかなー。

*1:だったら Don't Repeat Yourself なんて誤解しやすい名前、やめてほしいわ。