2013-12-01 2 views
2

Я думаю, что это видно из этого кода, что я пытается делать, то есть изменить 'blue к 'purple:Использование пользовательской функции добытчика в инкубаторе с SETF

CL-USER> (defparameter myassoc '((color red blue) (shape circle square))) 
MYASSOC 
CL-USER> myassoc 
((COLOR RED BLUE) (SHAPE CIRCLE SQUARE)) 
CL-USER> (defun getsecondof (assoc) (second (rest (assoc assoc myassoc)))) 
GETSECONDOF 
CL-USER> (getsecondof 'color) 
BLUE 
CL-USER> (setf (getsecondof 'color) 'purple) 
; in: SETF (GETSECONDOF 'COLOR) 
;  (FUNCALL #'(SETF GETSECONDOF) #:NEW954 'COLOR) 
; ==> 
; (SB-C::%FUNCALL #'(SETF GETSECONDOF) #:NEW954 'COLOR) 
; 
; caught STYLE-WARNING: 
; undefined function: (SETF GETSECONDOF) 
; 

Теперь, если вместо того, чтобы использовать моя собственная функция getsecondof с setf Я вместо этого передаю встроенное выражение CL, чтобы извлечь местоположение, которое я хочу изменить, оно работает.

Можно ли использовать пользовательские геттеры как сеттеры с setf?

ответ

3

Вы должны определить setf для него:

(defun (setf getsecondof) (assoc value) 
    (setf (caddr (assoc assoc myassoc)) value)) ; (caddr x) == (second (rest x)) 

(setf (getsecondof 'color) 'purple) ; ==> PURPLE 
(getsecondof 'color) ; ==> PURPLE 
+0

это почти больше смысла просто сделать обычную функцию для установки что-то, так как работа, кажется, примерно то же самое, и то функция, возможно, была бы более ясной или конкретной. – johnbakers

+0

@OpenLearner. Если вы будете следовать подходу, описанному Сильвертером, то при документировании вашей функции вы будете называть 'getecondof' _ _ _cess___cess__, так же, как HyperSpec [называет' car 'accessor] (http://www.lispworks.com/documentation/HyperSpec/ Тело/f_car_c.htm). Вы также можете определить функцию пользовательских настроек (например, ['rplaca'] (http://www.lispworks.com/documentation/HyperSpec/Body/f_rplaca.htm), но это можно было бы назвать функцией, а не Accessor. Удобно определять помощники, когда это необходимо, поскольку это одно имя функции, которое нужно запомнить. –

+0

@OpenLearner: После того, как вы определили 'setf', вы можете рассматривать эту вещь как _place_. Есть больше функций, которые занимают место как аргумент, например 'rotatef',' shiftf', 'push',' pop', 'incf',' decf'. – Svante

Смежные вопросы