2016-10-04 2 views
4

런타임에 클래스를 생성해야합니다. 예를 들어 평가에 의존하지 않아도됩니다.Common-Lisp에서 런타임에 클래스를 이식 가능하게 만드는 방법 CLOS

(defparameter *my-class* 
    (make-instance 'standard-class 
       :name 'my-class 
       :direct-slots '((:name x :readers (get-x) :writers ((setf get-x)))))) 

(defparameter *my-instance* (make-instance *my-class*)) 

(setf (get-x *my-instance*) 42) ;; => 42 
: 메타 클래스 프로토콜은 완전히 공통 리스프에서 표준화되지 않는다는 것을 알고는 The Common Lisp Object System MetaObject Protocol을 탐색 한 후, 나는 클래스를 생성 인스턴스화하고, 숫자로 인스턴스의 슬롯 값을 설정하려면 다음 코드를 시도

불행하게도이 코드는 SBCL에서 제대로 작동하지만 클래스 생성이 작동하는 것 같다 CCL에 있지만, 다음과 같은 오류가 발생 (make-instance *my-class*) 인스턴스 작성 :

There is no applicable method for the generic function: 
    #<STANDARD-GENERIC-FUNCTION INITIALIZE-INSTANCE #x30200002481F> 
when called with arguments: 
    (#<error printing CONS #x302001A9F6A3> 
    [Condition of type CCL:NO-APPLICABLE-METHOD-EXISTS] 

내가 closer-mop 패키지보고 시도를 숨겨야하는 메타에 대한 다양한 구현 간의 차이점 - 객체 프로토콜,하지만 내 모든 범위에서 유용한 기능이나 클래스를 찾을 수 없습니다.

그래서 질문입니다 : 클래스를 만들고 런타임시에 직접 metaclass level of CLOS를 사용하여 이식 할 수있는 이식성있는 방법이 있습니까?

+0

, 당신은 [보장 수준 (http://mop.lisp.se/dictionary.html#ensure-class) 시도하거나 수있는 [확인-클래스 사용하여 클래스 (http://mop.lisp.se/dictionary.html#ensure-class-using-class). – coredump

+1

직접 수퍼 클래스도 지정하면 CCL이 작동하는 것처럼 보입니다. : direct-superclasses (list (find-class 'standard-object))' – jkiiski

+0

감사합니다. @jkiiski, 문제는 내가 수퍼 클래스를 지정해야한다는 것입니다. 답변으로 게시하면 동의 할 것입니다. – Renzo

답변

3

CCL에서는 수동으로 직접 수퍼 클래스를 지정해야하는 것처럼 보입니다.

(defparameter *my-class* 
    (make-instance 'standard-class 
       :name 'my-class 
       :direct-slots '((:name x :readers (get-x) :writers ((setf get-x)))) 
       :direct-superclasses (list (find-class 'standard-object)))) 
3

일반적으로 ENSURE-CLASS을 사용하여 클래스를 만듭니다. ENSURE-CLASS의 목적은 DEFCLASS과 기능상 동일해야합니다. 특별한 구현 특정 사항을 제외하면 DEFCLASS - 예를 들어 개발 환경의 기능을 지원합니다.

MAKE-INSTANCE을 사용할 수 있지만 예를 들어 해당 이름으로 클래스를 등록하지 않습니다. 또한 추가로 ENSURE-CLASS-USING-CLASS 메소드를 호출하지 않습니다.

메타 클래스의 기본값은 standard-class이므로 CCL도 직접 슈퍼 클래스에 대한 기본값을 계산해야합니다. 이는 불행하게도 아닙니다.

가까운 클로 쓰은 이러한 비 호환성 문제를 해결하지만 확인하지는 않았 으면합니다. CCL에서

:

? (ensure-class 'my-class 
       :direct-slots '((:name x 
           :readers (get-x) 
           :writers ((setf get-x)))) 
       :direct-superclasses (list (find-class 'standard-object))) 
#<STANDARD-CLASS MY-CLASS> 
? (find-class 'my-class) 
#<STANDARD-CLASS MY-CLASS> 
? (let ((foo (make-instance 'my-class))) 
    (setf (get-x foo) 10) 
    (incf (get-x foo) 32) 
    (get-x foo)) 
42 

LispWorks 실제로 제대로 않습니다. 메타 클래스의 기본값은 standard-class이며 직접 수퍼 클래스는 standard-object입니다. 가까이-걸레로

CL-USER 25 > (clos:ensure-class 'foobar 
       :direct-slots '((:name x 
            :readers (get-x) 
            :writers ((setf get-x))))) 
#<STANDARD-CLASS FOOBAR 4020001713> 

CL-USER 26 > (class-direct-superclasses *) 
(#<STANDARD-CLASS STANDARD-OBJECT 40E018E313>) 
+0

답장을 보내 주셔서 감사합니다. – Renzo

관련 문제