From: Pascal Costanza
Subject: Re: Setting a value programatically given the name of an accessor.
Date: 
Message-ID: <51p89uF1knkrrU1@mid.individual.net>
Madhu wrote:
> Helu. Given the name of an accessor, how best to set the value
> programatically?  For example:
> 
> * (defstruct struct1 slot1)
> STRUCT1
> 
> * (setq $a (make-struct1))
> #S(STRUCT1 :SLOT1 NIL)
> 
> * (defun setslot (object slot-name new-value)
> 	(funcall (fdefinition `(setf ,slot-name)) new-value object ))
> SETSLOT
> 
> * (setslot $a 'struct1-slot1 10)
> 10
> 
> Is this (i.e. guessing the setf function name, and funcalling its
> fdefinition) the only route available? Do you know any other way to do
> this?

What's wrong with (setf (slot-name object) new-value) ?!?

If you want more flexibility wrt naming accessors, it may be better to 
switch to CLOS classes.

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: Setting a value programatically given the name of an accessor.
Date: 
Message-ID: <51pnluF1lc4fmU1@mid.individual.net>
Madhu wrote:
> * Pascal Costanza <···············@mid.individual.net> :
> |> * (defun setslot (object slot-name new-value)
> |>      (funcall (fdefinition `(setf ,slot-name)) new-value object ))
> |> SETSLOT
> |> 
> |> * (setslot $a 'struct1-slot1 10)
> |> 10
> |> 
> |> Is this (i.e. guessing the setf function name, and funcalling its
> |> fdefinition) the only route available? Do you know any other way to do
> |> this?
> |
> | What's wrong with (setf (slot-name object) new-value) ?!?
> 
> That would involve a call to EVAL wouldn't it?
> 
> (defun setslot (object slot-name new-value)
>    (eval `(setf (,slot-name object) new-value)))
> 
> 
> I think was just following the rule of a thumb and ruling that out :)
> Let me attempt to sketch a more concrete scenario of I want to use
> this: Assuming a condition called 'slot-already-set is defined..
> 
> 
> (cond ((not (null (struct1-slot1 $a)))
>        (error 'slot-already-set :object $a :accessor 'struct1-slot1
>                                 :new-value 10))
>       (t (setf (struct1-slot1 $a) 10)))
> 
> 
> Then, when handling the error, I can use SETSLOT to set the value. For
> example, I can prompt the user with a KEEP and REPLACE restarts. The
> REPLACE restart would use SETSLOT to set the value. SETSLOT would work
> off the accessor name, which is also needed to describe the condition.
> Does this scenario make sense?  Am I missing a better way of doing
> this?

Pass a function that does the job for you, like this:

(error 'slot-already-set ....
   :setter (lambda (... parameterize as needed ...)
             (setf (slot-name object) value)))




Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/