From: Björn Lindberg
Subject: Best way to set object slots when loading from file?
Date: 
Message-ID: <hcsy8t9afh4.fsf@knatte.nada.kth.se>
Consider the following class:

(defclass foo ()
  ((alpha :initarg :alpha :accessor alpha)
   (beta :initarg :beta :accessor beta)))

Now, I want to initialise an instance of that class from a file. At
first, I simply chose the following format for my file:

(foo :alpha "A" :beta "B")
(...)
(...)

Then I could READ one object at a time, and just do 
(apply #'make-instance read-object) for each instance. Now, for
various reasons, I want to change my file format to the following:

(foo (alpha "A")
     (beta "B"))
(... etc ...)

Ie, more markup-language like, and I am pondering the best way to
initialise the slots. I can think of a couple of different ways:

1) Convert the first symbol in each subelement (eg alpha, beta) to one
   in the keyword package, append the subelement lists, and then do as
   above. This seems a bit ugly, but is the only way I can see to
   initialise the slots at the same time as creating the object.

2) First create an "empty" instance, and then do 
   (setf (slot-value instance slot) value) for each subelement, where
   slot = {alpha, beta}, and value = {"A", "B"} in turn. This has the
   disadvantage that it breaks encapsulation in a way, since
   now the slots are locked. If I later would like to change "alpha"
   so that it is computed instead of being a slot, I cannot.

3) Create an empty instance, and then for each subelement do
   (setf (accessor instance) value), where accessor is the car of the
   subelement (alpha, beta), and value the cadr (in turn). Here I am
   locking the names of the accessors, but it seems slightly better
   than (2).

Is there a "best" way to do what I want?


Bj�rn

From: Rahul Jain
Subject: Re: Best way to set object slots when loading from file?
Date: 
Message-ID: <87hdzxskba.fsf@nyct.net>
·······@nada.kth.se (Bj�rn Lindberg) writes:

> Is there a "best" way to do what I want?

Define FOO as a macro that transforms the expression into a
MAKE-INSTANCE form?

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Thomas F. Burdick
Subject: Re: Best way to set object slots when loading from file?
Date: 
Message-ID: <xcv65gd2wke.fsf@famine.OCF.Berkeley.EDU>
·······@nada.kth.se (Bj�rn Lindberg) writes:

> Is there a "best" way to do what I want?

If you're not familiar with the MOP, you might check out the following
functions:

  FIND-CLASS
  CLASS-SLOTS
  SLOT-DEFINITION-NAME
  SLOT-DEFINITION-INITARGS

Eg:

  (defclass foo ()
    ((alpha :initarg alpha)
     (beta :initarg beta :initarg :beta)))

  (loop with class = (find-class 'foo)
        for slot in (class-slots class)
        for name = (slot-definition-name slot)
        for initargs = (slot-definition-initargs slot)
        do (format t "Slot ~A has initargs: ~A~%" name initargs))

  Slot ALPHA has initargs (ALPHA)
  Slot BETA has initargs (BETA :BETA)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Wade Humeniuk
Subject: Re: Best way to set object slots when loading from file?
Date: 
Message-ID: <96uEb.111051$bC.90149@clgrps13>
Bj�rn Lindberg wrote:
> Consider the following class:
> 
> (defclass foo ()
>   ((alpha :initarg :alpha :accessor alpha)
>    (beta :initarg :beta :accessor beta)))
...
> Is there a "best" way to do what I want?
> 

Best way is to leave the file in the canonical make-instance
form.

Second best way,

Change the class definition to

(defclass foo ()
    ((alpha :initarg alpha :initarg :alpha :accessor alpha)
     (beta :initarg beta :initarg :beta :accessor beta)))

Apply make-instance by

(apply #'make-instance 'foo (apply #'append '((alpha "H") (beta "I"))))

Wade
From: Björn Lindberg
Subject: Re: Best way to set object slots when loading from file?
Date: 
Message-ID: <hcsad5puh8k.fsf@knatte.nada.kth.se>
Wade Humeniuk <········@delete-this-antispam-device.telus.net> writes:

> Bj�rn Lindberg wrote:
> > Consider the following class:
> > (defclass foo ()
> >   ((alpha :initarg :alpha :accessor alpha)
> >    (beta :initarg :beta :accessor beta)))
> ...
> > Is there a "best" way to do what I want?
> >
> 
> Best way is to leave the file in the canonical make-instance
> form.

I forgot to mention that one of the reasons I want to change the
format is that I will also save objects to a file in the same format,
so if I keep the make-instance form, I will instead have some trouble
saving it in that form (I have to convert the slots to keyword initarg
form). Or wait, I think it would be possible to find out the initargs
via the MOP as Thomas outlines in another post?

> Second best way,
> 
> Change the class definition to
> 
> (defclass foo ()
>     ((alpha :initarg alpha :initarg :alpha :accessor alpha)
>      (beta :initarg beta :initarg :beta :accessor beta)))
> 
> Apply make-instance by
> 
> (apply #'make-instance 'foo (apply #'append '((alpha "H") (beta "I"))))

This seems good. I didn't know you could specify more than one initarg
per slot. As usual, Lisp goes out of its way to get out of my way. :-)


Bj�rn
From: Arthur Lemmens
Subject: Re: Best way to set object slots when loading from file?
Date: 
Message-ID: <opr0fh72hmk6vmsw@news.xs4all.nl>
Bj�rn Lindberg <·······@nada.kth.se> wrote:

> I forgot to mention that one of the reasons I want to change the
> format is that I will also save objects to a file in the same format,
> so if I keep the make-instance form, I will instead have some trouble
> saving it in that form (I have to convert the slots to keyword initarg
> form). Or wait, I think it would be possible to find out the initargs
> via the MOP as Thomas outlines in another post?

You could also define methods on MAKE-LOAD-FORM (see the Hyperspec),
write those forms to your file, and just LOAD the file when you need to.
This wouldn't work well if you want to manually edit the file, though.

Regards,

Arthur Lemmens