Next: , Previous: , Up: API Reference   [Contents][Index]


3.7 Stores

Grip module that provides the <store> class and its methods, which you may import using:

(use-modules (grip store))

Conceptually, a store - as in storage - is a simple key-value database, based on Goops and Association Lists, meant to be used to handle small number of entries only1.

Store entry keys are symbols, and equality tests use eq? (it uses assq and assq- prefixed association lists procedures). In a store, there can only be a single entry for a given key (stores do not use the acons procedure)2.

Like in scheme, methods that mutate a <store> inventory are postfixed using !. In scheme, set! is a syntax, and therefore it is not possible to create a generic function for its name and add a method with its code … as a consequence, we had to choose another name, and went for set-!

Here is a small (incomplete) example:

(define a-store
        (init! (make <store>)
               '((foo . bar) (baz . 2))))

(save a-store "/tmp/a-store")
-|
$3 = #t

(load! (make <store>)
       "/tmp/a-store" #:no-checks #t)
-|
$4 = #<<store> 560a1d7aaba0>

(inventory a-store)
-|
$5 = ((foo . bar) (baz . 2))

…

Class, Methods and Procedures

<store>
get
ref
set-!
remove!
inventory
init!
load!
save
store-inventory?

Class, methods and Procedures

Class: <store>

Slot definition:

store

#:init-keyword #:store
#:init-thunk list

Note:

Method: get (self <store>) (key <symbol>)

Returns the self (key . value) pair for the given key, if it exists. Otherwise, it returns #f.

Method: ref (self <store>) (key <symbol>)

Returns the self value for the given key, if it exists. Otherwise, it returns #f.

When the returned value is #f, it can be either because key was not found, or that its value is #f: if you need to differentiate these cases, use get.

Method: set-! (self <store>) (key <symbol>) val

Returns the self store inventory.

Either reassociate key with val if the key existed already, or otherwise, add a new (key . val) to the self store inventory.

Method: remove! (self <store>) (key <symbol>)

Returns the self store inventory.

Removes the self (key . value) pair for the given key, if it exists.

Method: inventory (self <store>)

Returns the self store inventory (the content of the self store slot).

Method: init! (self <store>) vals [#:no-checks #f]

Returns self.

Sets the self store inventory to vals. Unless #:no-checks is #t - to be used with caution and at your own risk - this method calls store-inventory? and raises an exception if vals is not a well-formed store inventory.

Method: load! (self <store>) filename [#:no-checks #f]

Returns self.

Sets the self store inventory to the content of filename. Unless #:no-checks is #t - to be used with caution and at your own risk - this method calls store-inventory? and raises an exception if the content of filename is not a well-formed store inventory.

Method: save (self <store>) filename

The return value is unspecified.

Saves the store inventory for self in filename.

Procedure: store-inventory? vals

Return three values:

#t 'well-formed #t

Everything is fine.

#f 'not-a-pair PAIR

One of the entry is ot a well-formed pair.

#f 'wrong-key-type PAIR

One of the keys was find not to be a symbol.

#f 'duplicate-key PAIR

One of the key has a duplicate entry.

A well-formed store inventory is either an empty list or a list of (KEY . VALUE) PAIRs, where KEY is a symbol for all PAIRs and all KEYs are unique.


Footnotes

(1)

Strictly speaking, there is no limit on the number of entries a store can handle (appart from available memory size) , but association lists won’t give you decent performance, unless the number of items is kept small: below one hundred entries, it will probably be fine, otherwise you should consider using a real database system instead.

(2)

Though technically speaking it is possible, as in (slot-set! <my-store> 'store (acons 'white 'cat (slot-ref <my-store> 'store))) it is not recommended, for two reasons: (a) because you may inadvertently introduce a (KEY . VALUE) pair where KEY would not be a symbol, and (b) because there is much better solution: if that is what you want, then subclass <store>, for example <store-me> (store - multiple entries) and provide an additional method, for example set-me!, which, by defintion (Goops generic functions, dispatch mechanism and applicable methods selection), would only work if its key argument is a symbol … et voilĂ !


Next: , Previous: , Up: API Reference   [Contents][Index]