2012-03-14 10 views
2

私は次のクラスを持って、そしてより多くの彼らのような:クラスのために類似のスロットを多数作成するにはどうすればよいですか?

(defclass weapon() 
    ((base-slice-damage 
    :documentation "Base slice damage dealt by weapon" 
    :reader base-slice-damage 
    :initform 0 
    :initarg :base-slice-damage) 
    (base-blunt-damage 
    :reader base-blunt-damage 
    :initform 0 
    :initarg :base-blunt-damage) 
    (base-pierce-damage 
    :reader base-pierce-damage 
    :initform 0 
    :initarg :base-pierce-damage))) 

(defclass dagger (weapon) 
    ((base-slice-damage 
    :initform 3) 
    (base-pierce-damage 
    :initform 6))) 

(defclass attack() 
    ((slice-damage-dealt 
    :initarg :slice-damage-dealt 
    :reader slice-damage-dealt) 
    (blunt-damage-dealt 
    :initarg :blunt-damage-dealt 
    :reader blunt-damage-dealt) 
    (pierce-damage-dealth 
    :initarg :pierce-damage-dealt 
    :reader pierce-damage-dealt))) 

あなたが見ることができるように、繰り返しがたくさんあります。 2つのクラスについて、私のスロットはすべて同じオプションを持ち、スライス、ブラント、またはピアスのいずれかによってのみ異なります。

私は属性クラスを定義するためにマクロを使用して、ちょうどのものを混合について考えてきましたこれは、私がこれまで持っているものです。

(defmacro defattrclass (attr-name &body class-options) 
    `(defclass ,(symb attr-name '-attr)() 
    ((,attr-name 
     ,@class-options)))) 

しかし、これは本当に十分行っておりません。


編集:私はそれを完全に満足していないのに、私は、これを作ってみた

(defmacro defattrclass (attr-name &body class-options) 
    `(defclass ,(symb attr-name '-attr)() 
    ((,attr-name 
     ,@class-options)))) 

(defmacro defattrclasses (attr-names &body class-options) 
    `(progn 
    ,@(loop for attr-name in attr-names collect 
      `(defattrclass ,attr-name ,@class-options)))) 
+3

http://www.reddit.com/r/lisp/comments/qwy5o/how_can_i_quickly_create_many_similar_slots_for_a/(それはあなたが2つの場所で質問をしている場合、明示的には良いネチケットです)。 –

+0

ありがとう、私は気づいていない – higginbotham

答えて

2

必要な機能のない、非常に100%のカバレッジが、私はしばらくの間、このマクロを使用してきた:

(defmacro defclass-default (class-name superclasses slots &rest class-options) 
    "Shorthand defclass syntax; structure similar to defclass 
    Pass three values: slot-name, :initform, and :documentation 
    Everything else gets filled in to standard defaults" 
    `(defclass 
    ,class-name 
    ,superclasses 
    ,(mapcar (lambda (x) `(,(first x) 
          :accessor ,(first x) 
          :initarg ,(intern (symbol-name (first x)) "KEYWORD") 
          :initform ,(second x) 
          :documentation ,(third x))) 
       slots) 
    ,@class-options)) 

を使用するには:

CL-USER> 
(defclass-default weapon() 
    ((base-slice-damage 0 "Base slice damage dealt by a weapon") 
    (base-blunt-damage 0 "Needs a doc") 
    (base-pierce-damage 0 "Needs a doc"))) 
#<STANDARD-CLASS WEAPON> 
CL-USER> 
+0

これは役に立ちました、ありがとう。私はそれがあまりにも狂ってスロットのバリエーションを許可するのだろうかと思っていますか?たとえば、アクセサーの代わりにリーダーだけを作成したい場合もあります。 – higginbotham

+0

あなたまで言語とあなたの問題との間の正しい交差点を見つけてください。マクロを使って、あなたは本当に何でもできます。 –

1

次の3つの分野(slicebluntpierce)とクラスdamageを必要とするよう私見それが見えます。あなたは、weapon内部でそのクラスを使用することができますattackなど

+0

私はこれらの行に沿って何かを考えていました。しかし、私はまた、 "スライスダメージ受信"やその他のバリエーションのようなスロットを作成しています。 – higginbotham

+0

複数の継承を使用してトラクションを得ることができます(たとえば、スロットミックスを作成するなど) –

関連する問題