297 lines
16 KiB
HTML
297 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<!-- This manual documents Guile version 3.0.10.
|
|
|
|
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
|
|
Inc.
|
|
|
|
Copyright (C) 2021 Maxime Devos
|
|
|
|
Copyright (C) 2024 Tomas Volf
|
|
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
any later version published by the Free Software Foundation; with no
|
|
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
|
copy of the license is included in the section entitled "GNU Free
|
|
Documentation License." -->
|
|
<title>Slot Options (Guile Reference Manual)</title>
|
|
|
|
<meta name="description" content="Slot Options (Guile Reference Manual)">
|
|
<meta name="keywords" content="Slot Options (Guile Reference Manual)">
|
|
<meta name="resource-type" content="document">
|
|
<meta name="distribution" content="global">
|
|
<meta name="Generator" content=".texi2any-real">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
<link href="index.html" rel="start" title="Top">
|
|
<link href="Concept-Index.html" rel="index" title="Concept Index">
|
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
|
<link href="GOOPS.html" rel="up" title="GOOPS">
|
|
<link href="Slot-Description-Example.html" rel="next" title="Slot Description Example">
|
|
<link href="Instance-Creation.html" rel="prev" title="Instance Creation">
|
|
<style type="text/css">
|
|
<!--
|
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
|
div.example {margin-left: 3.2em}
|
|
span:hover a.copiable-link {visibility: visible}
|
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
|
ul.mark-bullet {list-style-type: disc}
|
|
-->
|
|
</style>
|
|
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
|
|
|
|
|
|
</head>
|
|
|
|
<body lang="en">
|
|
<div class="section-level-extent" id="Slot-Options">
|
|
<div class="nav-panel">
|
|
<p>
|
|
Next: <a href="Slot-Description-Example.html" accesskey="n" rel="next">Illustrating Slot Description</a>, Previous: <a href="Instance-Creation.html" accesskey="p" rel="prev">Instance Creation and Slot Access</a>, Up: <a href="GOOPS.html" accesskey="u" rel="up">GOOPS</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<hr>
|
|
<h3 class="section" id="Slot-Options-1"><span>8.4 Slot Options<a class="copiable-link" href="#Slot-Options-1"> ¶</a></span></h3>
|
|
|
|
<p>When specifying a slot (in a <code class="code">(define-class …)</code> form),
|
|
various options can be specified in addition to the slot’s name. Each
|
|
option is specified by a keyword. The list of possible keywords is
|
|
as follows.
|
|
</p>
|
|
<dl class="first-deffn">
|
|
<dt class="deffn" id="index-_0023_003ainit_002dvalue"><span class="category-def">slot option: </span><span><strong class="def-name">#:init-value</strong> <var class="def-var-arguments">init-value</var><a class="copiable-link" href="#index-_0023_003ainit_002dvalue"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003ainit_002dform"><span class="category-def">slot option: </span><span><strong class="def-name">#:init-form</strong> <var class="def-var-arguments">init-form</var><a class="copiable-link" href="#index-_0023_003ainit_002dform"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003ainit_002dthunk"><span class="category-def">slot option: </span><span><strong class="def-name">#:init-thunk</strong> <var class="def-var-arguments">init-thunk</var><a class="copiable-link" href="#index-_0023_003ainit_002dthunk"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003ainit_002dkeyword"><span class="category-def">slot option: </span><span><strong class="def-name">#:init-keyword</strong> <var class="def-var-arguments">init-keyword</var><a class="copiable-link" href="#index-_0023_003ainit_002dkeyword"> ¶</a></span></dt>
|
|
<dd><p>These options provide various ways to specify how to initialize the
|
|
slot’s value at instance creation time.
|
|
<a class="index-entry-id" id="index-default-slot-value"></a>
|
|
</p>
|
|
<p><var class="var">init-value</var> specifies a fixed initial slot value (shared across all
|
|
new instances of the class).
|
|
</p>
|
|
<p><var class="var">init-thunk</var> specifies a thunk that will provide a default value for
|
|
the slot. The thunk is called when a new instance is created and should
|
|
return the desired initial slot value.
|
|
</p>
|
|
<p><var class="var">init-form</var> specifies a form that, when evaluated, will return
|
|
an initial value for the slot. The form is evaluated each time that
|
|
an instance of the class is created, in the lexical environment of the
|
|
containing <code class="code">define-class</code> expression.
|
|
</p>
|
|
<p><var class="var">init-keyword</var> specifies a keyword that can be used to pass an
|
|
initial slot value to <code class="code">make</code> when creating a new instance.
|
|
</p>
|
|
<p>Note that, since an <code class="code">init-value</code> value is shared across all
|
|
instances of a class, you should only use it when the initial value is
|
|
an immutable value, like a constant. If you want to initialize a slot
|
|
with a fresh, independently mutable value, you should use
|
|
<code class="code">init-thunk</code> or <code class="code">init-form</code> instead. Consider the following
|
|
example.
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-class <chbouib> ()
|
|
(hashtab #:init-value (make-hash-table)))
|
|
</pre></div>
|
|
|
|
<p>Here only one hash table is created and all instances of
|
|
<code class="code"><chbouib></code> have their <code class="code">hashtab</code> slot refer to it. In order
|
|
to have each instance of <code class="code"><chbouib></code> refer to a new hash table, you
|
|
should instead write:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-class <chbouib> ()
|
|
(hashtab #:init-thunk make-hash-table))
|
|
</pre></div>
|
|
|
|
<p>or:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-class <chbouib> ()
|
|
(hashtab #:init-form (make-hash-table)))
|
|
</pre></div>
|
|
|
|
<p>If more than one of these options is specified for the same slot, the
|
|
order of precedence, highest first is
|
|
</p>
|
|
<ul class="itemize mark-bullet">
|
|
<li><code class="code">#:init-keyword</code>, if <var class="var">init-keyword</var> is present in the options
|
|
passed to <code class="code">make</code>
|
|
|
|
</li><li><code class="code">#:init-thunk</code>, <code class="code">#:init-form</code> or <code class="code">#:init-value</code>.
|
|
</li></ul>
|
|
|
|
<p>If the slot definition contains more than one initialization option of
|
|
the same precedence, the later ones are ignored. If a slot is not
|
|
initialized at all, its value is unbound.
|
|
</p>
|
|
<p>In general, slots that are shared between more than one instance are
|
|
only initialized at new instance creation time if the slot value is
|
|
unbound at that time. However, if the new instance creation specifies
|
|
a valid init keyword and value for a shared slot, the slot is
|
|
re-initialized regardless of its previous value.
|
|
</p>
|
|
<p>Note, however, that the power of GOOPS’ metaobject protocol means that
|
|
everything written here may be customized or overridden for particular
|
|
classes! The slot initializations described here are performed by the least
|
|
specialized method of the generic function <code class="code">initialize</code>, whose
|
|
signature is
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(define-method (initialize (object <object>) initargs) ...)
|
|
</pre></div>
|
|
|
|
<p>The initialization of instances of any given class can be customized by
|
|
defining a <code class="code">initialize</code> method that is specialized for that class,
|
|
and the author of the specialized method may decide to call
|
|
<code class="code">next-method</code> - which will result in a call to the next less
|
|
specialized <code class="code">initialize</code> method - at any point within the
|
|
specialized code, or maybe not at all. In general, therefore, the
|
|
initialization mechanisms described here may be modified or overridden by
|
|
more specialized code, or may not be supported at all for particular
|
|
classes.
|
|
</p></dd></dl>
|
|
|
|
<dl class="first-deffn">
|
|
<dt class="deffn" id="index-_0023_003agetter"><span class="category-def">slot option: </span><span><strong class="def-name">#:getter</strong> <var class="def-var-arguments">getter</var><a class="copiable-link" href="#index-_0023_003agetter"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003asetter"><span class="category-def">slot option: </span><span><strong class="def-name">#:setter</strong> <var class="def-var-arguments">setter</var><a class="copiable-link" href="#index-_0023_003asetter"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003aaccessor"><span class="category-def">slot option: </span><span><strong class="def-name">#:accessor</strong> <var class="def-var-arguments">accessor</var><a class="copiable-link" href="#index-_0023_003aaccessor"> ¶</a></span></dt>
|
|
<dd><p>Given an object <var class="var">obj</var> with slots named <code class="code">foo</code> and <code class="code">bar</code>, it
|
|
is always possible to read and write those slots by calling
|
|
<code class="code">slot-ref</code> and <code class="code">slot-set!</code> with the relevant slot name; for
|
|
example:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(slot-ref <var class="var">obj</var> 'foo)
|
|
(slot-set! <var class="var">obj</var> 'bar 25)
|
|
</pre></div>
|
|
|
|
<p>The <code class="code">#:getter</code>, <code class="code">#:setter</code> and <code class="code">#:accessor</code> options, if
|
|
present, tell GOOPS to create generic function and method definitions
|
|
that can be used to get and set the slot value more conveniently.
|
|
<var class="var">getter</var> specifies a generic function to which GOOPS will add a
|
|
method for getting the slot value. <var class="var">setter</var> specifies a generic
|
|
function to which GOOPS will add a method for setting the slot value.
|
|
<var class="var">accessor</var> specifies an accessor to which GOOPS will add methods for
|
|
both getting and setting the slot value.
|
|
</p>
|
|
<p>So if a class includes a slot definition like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(c #:getter get-count #:setter set-count #:accessor count)
|
|
</pre></div>
|
|
|
|
<p>GOOPS defines generic function methods such that the slot value can be
|
|
referenced using either the getter or the accessor -
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(let ((current-count (get-count obj))) ...)
|
|
(let ((current-count (count obj))) ...)
|
|
</pre></div>
|
|
|
|
<p>- and set using either the setter or the accessor -
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example-preformatted">(set-count obj (+ 1 current-count))
|
|
(set! (count obj) (+ 1 current-count))
|
|
</pre></div>
|
|
|
|
<p>Note that
|
|
</p>
|
|
<ul class="itemize mark-bullet">
|
|
<li>with an accessor, the slot value is set using the generalized
|
|
<code class="code">set!</code> syntax
|
|
|
|
</li><li>in practice, it is unusual for a slot to use all three of these options:
|
|
read-only, write-only and read-write slots would typically use only
|
|
<code class="code">#:getter</code>, <code class="code">#:setter</code> and <code class="code">#:accessor</code> options
|
|
respectively.
|
|
</li></ul>
|
|
|
|
<p>The binding of the specified names is done in the environment of the
|
|
<code class="code">define-class</code> expression. If the names are already bound (in that
|
|
environment) to values that cannot be upgraded to generic functions,
|
|
those values are overwritten when the <code class="code">define-class</code> expression is
|
|
evaluated. For more detail, see <a class="ref" href="Generic-Function-Internals.html">ensure-generic</a>.
|
|
</p></dd></dl>
|
|
|
|
<dl class="first-deffn">
|
|
<dt class="deffn" id="index-_0023_003aallocation"><span class="category-def">slot option: </span><span><strong class="def-name">#:allocation</strong> <var class="def-var-arguments">allocation</var><a class="copiable-link" href="#index-_0023_003aallocation"> ¶</a></span></dt>
|
|
<dd><p>The <code class="code">#:allocation</code> option tells GOOPS how to allocate storage for
|
|
the slot. Possible values for <var class="var">allocation</var> are
|
|
</p>
|
|
<ul class="itemize mark-bullet">
|
|
<li><code class="code">#:instance</code>
|
|
|
|
<a class="index-entry-id" id="index-_0023_003ainstance"></a>
|
|
<p>Indicates that GOOPS should create separate storage for this slot in
|
|
each new instance of the containing class (and its subclasses). This is
|
|
the default.
|
|
</p>
|
|
</li><li><code class="code">#:class</code>
|
|
|
|
<a class="index-entry-id" id="index-_0023_003aclass"></a>
|
|
<p>Indicates that GOOPS should create storage for this slot that is shared
|
|
by all instances of the containing class (and its subclasses). In other
|
|
words, a slot in class <var class="var">C</var> with allocation <code class="code">#:class</code> is shared
|
|
by all <var class="var">instance</var>s for which <code class="code">(is-a? <var class="var">instance</var> <var class="var">c</var>)</code>.
|
|
This permits defining a kind of global variable which can be accessed
|
|
only by (in)direct instances of the class which defines the slot.
|
|
</p>
|
|
</li><li><code class="code">#:each-subclass</code>
|
|
|
|
<a class="index-entry-id" id="index-_0023_003aeach_002dsubclass"></a>
|
|
<p>Indicates that GOOPS should create storage for this slot that is shared
|
|
by all <em class="emph">direct</em> instances of the containing class, and that
|
|
whenever a subclass of the containing class is defined, GOOPS should
|
|
create a new storage for the slot that is shared by all <em class="emph">direct</em>
|
|
instances of the subclass. In other words, a slot with allocation
|
|
<code class="code">#:each-subclass</code> is shared by all instances with the same
|
|
<code class="code">class-of</code>.
|
|
</p>
|
|
</li><li><code class="code">#:virtual</code>
|
|
|
|
<a class="index-entry-id" id="index-_0023_003aslot_002dset_0021"></a>
|
|
<a class="index-entry-id" id="index-_0023_003aslot_002dref"></a>
|
|
<a class="index-entry-id" id="index-_0023_003avirtual"></a>
|
|
<p>Indicates that GOOPS should not allocate storage for this slot. The
|
|
slot definition must also include the <code class="code">#:slot-ref</code> and
|
|
<code class="code">#:slot-set!</code> options to specify how to reference and set the value
|
|
for this slot. See the example below.
|
|
</p></li></ul>
|
|
|
|
<p>Slot allocation options are processed when defining a new class by the
|
|
generic function <code class="code">compute-get-n-set</code>, which is specialized by the
|
|
class’s metaclass. Hence new types of slot allocation can be
|
|
implemented by defining a new metaclass and a method for
|
|
<code class="code">compute-get-n-set</code> that is specialized for the new metaclass. For
|
|
an example of how to do this, see <a class="ref" href="Customizing-Class-Definition.html">Customizing Class Definition</a>.
|
|
</p></dd></dl>
|
|
|
|
<dl class="first-deffn">
|
|
<dt class="deffn" id="index-_0023_003aslot_002dref-1"><span class="category-def">slot option: </span><span><strong class="def-name">#:slot-ref</strong> <var class="def-var-arguments">getter</var><a class="copiable-link" href="#index-_0023_003aslot_002dref-1"> ¶</a></span></dt>
|
|
<dt class="deffnx def-cmd-deffn" id="index-_0023_003aslot_002dset_0021-1"><span class="category-def">slot option: </span><span><strong class="def-name">#:slot-set!</strong> <var class="def-var-arguments">setter</var><a class="copiable-link" href="#index-_0023_003aslot_002dset_0021-1"> ¶</a></span></dt>
|
|
<dd><p>The <code class="code">#:slot-ref</code> and <code class="code">#:slot-set!</code> options must be specified
|
|
if the slot allocation is <code class="code">#:virtual</code>, and are ignored otherwise.
|
|
</p>
|
|
<p><var class="var">getter</var> should be a closure taking a single <var class="var">instance</var> parameter
|
|
that returns the current slot value. <var class="var">setter</var> should be a closure
|
|
taking two parameters - <var class="var">instance</var> and <var class="var">new-val</var> - that sets the
|
|
slot value to <var class="var">new-val</var>.
|
|
</p></dd></dl>
|
|
|
|
</div>
|
|
<hr>
|
|
<div class="nav-panel">
|
|
<p>
|
|
Next: <a href="Slot-Description-Example.html">Illustrating Slot Description</a>, Previous: <a href="Instance-Creation.html">Instance Creation and Slot Access</a>, Up: <a href="GOOPS.html">GOOPS</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|