2012-03-14 43 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))) 

正如你可以看到,有很多重複的。對於其中兩個類,我的插槽都具有相同的選項,並且僅根據它們是切片,鈍器還是穿孔而變化。 。

我想過使用宏來定義屬性類,然後就混合那些這是我到目前爲止有:

(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/(這是很好的網絡禮儀是明確的,如果你要問的問題在兩個地方) – 2012-03-15 00:11:18

+0

謝謝,我沒有意識到 – higginbotham 2012-03-15 19:44:11

回答

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 2012-03-15 19:46:23

+0

由你決定;找到語言和你的問題之間的正確交集;與宏,你真的可以做任何你想要的東西 – 2012-03-15 19:54:26

1

恕我直言,它看起來像你需要一個類damage有三個字段(slicebluntpierce)。您可以使用這個類裏面weaponattack

+0

我正在考慮沿着這些線的東西。不過,我也在創造像「切片損壞 - 收到」和其他變化的插槽。 – higginbotham 2012-03-15 19:48:34

+0

可能會獲得多重繼承的牽引力(例如,使槽混合) – 2012-03-15 19:57:07