Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Setting a value programatically given the name of an accessor.

1 view
Skip to first unread message
Message has been deleted

Pascal Costanza

unread,
Jan 24, 2007, 9:20:44 AM1/24/07
to
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/

Message has been deleted

Szymon

unread,
Jan 24, 2007, 12:44:35 PM1/24/07
to
Madhu wrote:

> * (defun setslot (object slot-name new-value)
> (funcall (fdefinition `(setf ,slot-name)) new-value object ))


I'm not sure of portability, from CLHS:

"The mechanism by which defstruct arranges for slot accessors to be usable with
setf is implementation-dependent; for example, it may use setf functions, setf
expanders, or some other implementation-dependent mechanism known to that
implementation's code for setf."

Regards, Szymon.

Pascal Costanza

unread,
Jan 24, 2007, 1:43:08 PM1/24/07
to
Madhu wrote:
> * Pascal Costanza <51p89uF...@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)))

Thomas A. Russ

unread,
Jan 24, 2007, 2:48:43 PM1/24/07
to
Madhu <eno...@meer.net> writes:

> Helu. Given the name of an accessor, how best to set the value
> programatically? For example:

...


> * (defun setslot (object slot-name new-value)
> (funcall (fdefinition `(setf ,slot-name)) new-value object ))
> SETSLOT

...


> 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?

Not in any portable fashion for DEFSTRUCT slots.

If you use CLOS, then you can use SLOT-VALUE which is SETF-able:

(setf (slot-value object slot-name) new-value)


Some Common Lisp implementations use CLOS for structures and there
slot-value will work for defstruct object, but there is no reason to
believe this has to be so.

--
Thomas A. Russ, USC/Information Sciences Institute

John Thingstad

unread,
Jan 26, 2007, 3:25:25 PM1/26/07
to
On Wed, 24 Jan 2007 13:13:06 +0100, Madhu <eno...@meer.net> 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?

> --
> Madhu

defstruct defines it's own accessors

(defstruct name
(slot1 nil)
(slot2 nil))

(defparameter *name* (make-name))

(setf (name-slot1 *name*) value))

If you don't like the default name you can use :conc-name

(defstruct (position-info (:conc-name pos-))
(found nil)
(previous nil)
(space nil))

(setf (pos-found *var*) t)

Works for individual variables too.

For more flexibillity use defclass.
The advantage of defstruct is mainly that it has less overhead.

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

Message has been deleted
0 new messages