I'm writing a bit of database program, and i would like to use an
assocation list of prompt for the user and the function to call and i
cannot figure out how to get the code to access the particular
elements of the structure.. here is a bit of code...
;+----
;| pilot database look up
;| christopher bowron - ········@cps.msu.edu
;| digital dreamland 1997
;+----
(defstruct person name major phone address email webpage)
(defvar *personinfo*)
(setq *personinfo*
'(("name : " . #'person-name)
("major : " . #'person-major)
("phone : " . #'person-phone)
("addrs : " . #'person-address)
("email : " . #'person-email)
("http : " . #'person-webpage)))
(defvar *input*)
;******************************************************************************
(defun get-search-criteria()
(let ((p (make-person)) item code)
(dolist (item *personinfo*)
(setq code `(setf (,(cdr item) p) (read-line)))
(setq code `(,(cdr item) p))
(format t "~a~%~a~%" code p)
(format t "~a" (car item))
;(funcall #'(lambda(x y) (setf x y)) code (read-line)))
;;; THIS LINE I DONT KNOW WHAT TO DO!!!
(setf (apply (cdr item) p) (read-line))
;;;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^????
)
p))
;******************************************************************************
if anyone can help me access this particular element of the structure
like this thank you.. or if you have a suggestion on a better
way... thanks in advance
--
-+- Christopher W. Bowron
-+- ········@cps.msu.edu
-+- http://www.cps.msu.edu/~bowronch
In article <············@msunews.cl.msu.edu>, ········@cps.msu.edu
(Christopher William Bowron) wrote:
> I'm writing a bit of database program, and i would like to use an
> assocation list of prompt for the user and the function to call and i
> cannot figure out how to get the code to access the particular
> elements of the structure.. here is a bit of code...
>
> ;+----
> ;| pilot database look up
> ;| christopher bowron - ········@cps.msu.edu
> ;| digital dreamland 1997
> ;+----
>
> (defstruct person name major phone address email webpage)
>
> (defvar *personinfo*)
> (setq *personinfo*
> '(("name : " . #'person-name)
> ("major : " . #'person-major)
> ("phone : " . #'person-phone)
> ("addrs : " . #'person-address)
> ("email : " . #'person-email)
> ("http : " . #'person-webpage)))
>
> (defvar *input*)
>
;***************************************************************************
***
> (defun get-search-criteria()
> (let ((p (make-person)) item code)
> (dolist (item *personinfo*)
> (setq code `(setf (,(cdr item) p) (read-line)))
> (setq code `(,(cdr item) p))
> (format t "~a~%~a~%" code p)
> (format t "~a" (car item))
> ;(funcall #'(lambda(x y) (setf x y)) code (read-line)))
>
> ;;; THIS LINE I DONT KNOW WHAT TO DO!!!
> (setf (apply (cdr item) p) (read-line))
> ;;;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^????
> )
> p))
>
>
;***************************************************************************
***
>
> if anyone can help me access this particular element of the structure
> like this thank you.. or if you have a suggestion on a better
> way... thanks in advance
Assuming that you are using Common Lisp, the following would work.
Are there simpler methods? One could use GET-SETF-METHOD.
In some implementations SETF with SLOT-VALUE on structures
works.
The best way (until you don't have some special performance needs)
would be to use DEFCLASS instead of DEFSTRUCT. As
a general rule, *I* would prefer DEFCLASS almost all the time.
Exceptions are simple objects where the speed of slot
access might be important.
(defstruct person name major phone address email webpage)
; We need the setter functions to be generated at compile time:
(defmacro define-accessors (name description)
`(defparameter ,name
(list ,@(loop for (name . accessor) in description
collect `(cons ,name (function
(lambda (object new-value)
(setf (,accessor object)
new-value))))))))
(define-accessors *personinfo*
(("name" . person-name)
("major" . person-major)
("phone" . person-phone)
("addrs" . person-address)
("email" . person-email)
("http" . person-webpage)))
(defun get-search-criteria (&optional (stream t))
(let ((p (make-person)))
(loop for (prompt . setter) in *personinfo*
do (format stream "~%~a : " prompt)
do (funcall setter p (read-line stream)))
p))
Not elegant, but works.
--
http://www.lavielle.com/~joswig/
In article <············@msunews.cl.msu.edu>,
Christopher William Bowron <········@cps.msu.edu> wrote:
>(setq *personinfo*
> '(("name : " . #'person-name)
> ("major : " . #'person-major)
> ("phone : " . #'person-phone)
> ("addrs : " . #'person-address)
> ("email : " . #'person-email)
> ("http : " . #'person-webpage)))
#'xxx is a reader macro that expands into (function xxx), which *evaluates*
to the function binding of XXX. But since you're quoting the alist, that
evaluation never happens. So later on you're trying to funcall a list that
begins with FUNCTION, which isn't a valid function. You need to evaluate
these expressions when constructing the alist:
(setq *personinfo*
(list
(cons "name : " #'person-name)
(cons "major : " #'person-major)
(cons "phone : " #'person-phone)
(cons "addrs : " #'person-address)
(cons "email : " #'person-email)
(cons "http : " #'person-webpage)))
Backquote can also be used to simplify it:
(setq *personinfo*
`(("name : " . ,#'person-name)
("major : " . ,#'person-major)
("phone : " . ,#'person-phone)
("addrs : " . ,#'person-address)
("email : " . ,#'person-email)
("http : " . ,#'person-webpage)))
--
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.