EDIT:我已经重新构造了这个问题,所以(希望)更容易回答。我是CL的新手,所以当我甚至不确定最好的描述方式是什么时,有时很难描述我想做什么:P
在过去的几周里,我一直在学习一些Common Lisp,我想知道在给定配置文件的情况下创建对象实例的最佳方法,该配置文件定义了类的一些槽值,但在分配值之前,这些值需要以某种形式规范化。
因此,举个简单的例子,如果我有以下类:
(defclass my-class ()
((name
:initarg :name
:accessor name)
(x
:initarg :x
:initform 10
:accessor x)
(y
:initarg :y
:initform nil
:accessor y)))
和
(defmethod initialize-instance :after ((obj my-class) &key)
(with-slots (x y)
obj
(setf y (* 2 x))))
我想要一种在外部文件中指定的方法,比如instance-a.lisp
(possibly-some-macro "A"
:x 5)
但是在构造实例时,必须首先对值x进行规范化。对make-instance
的最终调用看起来是这样的:
(make-instance 'my-class
:name (name-value-from-config)
:x (normalize (x-value-from-config))
其中(name-value-from-config)
为"A",(x值-来自配置)为5。注意:这两种形式仅用于占位符,以表明它应该使用配置中的值进行构造。
我最初的想法是将配置文件中的任何内容都变成一个哈希表或带有适当键的plist。
我不清楚你真正想做什么。
为什么要使用宏来创建对象?
-
宏会产生编译时的副作用。例如,该对象在文件编译期间应该是可用的。
-
宏提供了更方便的语法
但为了所有其他目的,不要试图做一些聪明的事情。通常我只会LOAD
一个Lisp文件进行配置。
(defparameter *instance-a*
(make-instance 'my-class :x 5 :y '(1 2 3)))
如果需要配置类:
(defparameter *a-class* 'my-class)
(defparameter *instance-a*
(make-instance *a-class* :x 5 :y '(1 2 3)))