Next: Creating Instances, Up: Defining New Types (Smobs)
To define a new type, the programmer must write four functions to manage instances of the type:
mark
SCM
values that the object
has stored. The default smob mark function does nothing.
See Garbage Collecting Smobs, for more details.
free
scm_make_smob_type
is non-zero)
using scm_gc_free
. See Garbage Collecting Smobs, for more
details.
This function operates while the heap is in an inconsistent state and
must therefore be careful. See Smobs, for details about what this
function is allowed to do.
print
display
or write
. The default print
function prints #<NAME ADDRESS>
where NAME
is the first
argument passed to scm_make_smob_type
. For more information on
printing, see Port Data.
equalp
equal?
function to compare two instances
of the same smob type, Guile calls this function. It should return
SCM_BOOL_T
if a and b should be considered
equal?
, or SCM_BOOL_F
otherwise. If equalp
is
NULL
, equal?
will assume that two instances of this type are
never equal?
unless they are eq?
.
To actually register the new smob type, call scm_make_smob_type
.
It returns a value of type scm_t_bits
which identifies the new
smob type.
The four special functions described above are registered by calling
one of scm_set_smob_mark
, scm_set_smob_free
,
scm_set_smob_print
, or scm_set_smob_equalp
, as
appropriate. Each function is intended to be used at most once per
type, and the call should be placed immediately following the call to
scm_make_smob_type
.
There can only be at most 256 different smob types in the system. Instead of registering a huge number of smob types (for example, one for each relevant C struct in your application), it is sometimes better to register just one and implement a second layer of type dispatching on top of it. This second layer might use the 16 extra bits to extend its type, for example.
Here is how one might declare and register a new type representing eight-bit gray-scale images:
#include <libguile.h> struct image { int width, height; char *pixels; /* The name of this image */ SCM name; /* A function to call when this image is modified, e.g., to update the screen, or SCM_BOOL_F if no action necessary */ SCM update_func; }; static scm_t_bits image_tag; void init_image_type (void) { image_tag = scm_make_smob_type ("image", sizeof (struct image)); scm_set_smob_mark (image_tag, mark_image); scm_set_smob_free (image_tag, free_image); scm_set_smob_print (image_tag, print_image); }