Keyword arguments are provided as a general feature for C functions.
However, Sod has special support for messages which accept keyword arguments
-(\xref{sec:concepts.methods.keywords}).
+(\xref{sec:concepts.methods.keywords}); and they play an essential role in
+the instance construction protocol (\xref{sec:concepts.lifecycle.birth}).
%%%--------------------------------------------------------------------------
\section{Messages and methods} \label{sec:concepts.methods}
necessary.
\end{enumerate}
The \descref{SOD_DECL}[macro]{mac} handles constructing instances with
-automatic storage duration (`on the stack'). Currently, there is no built-in
-support for constructing dynamically-allocated instances.
+automatic storage duration (`on the stack'). Programmers can add support for
+other allocation strategies by using the \descref{SOD_INIT}[macro]{mac} and
+the \descref{sod_init}{fun} and \descref{sod_initv}{fun} functions, which
+package up imprinting and initialization.
\subsubsection{Allocation}
Instances of most classes (specifically including those classes defined by
involves setting the instance's slots to appropriate values, and possibly
linking it into some larger data structure to keep track of it.
-Classes can declare initial values for their slots. A class object's @|init|
-slot points to a function which will establish the appropriate initial values
-for a new instance's slots. Slots are not initialized in any particularly
-useful order.
-
-The provided initialization protocol is extremely simplistic; most notably,
-it's not possible to pass parameters into the initialization process.
-Classes which have more complex requirements will need to define and
-implement their own additional (or alternative) protocols.
+Initialization is performed by sending the imprinted instance an @|init|
+message, defined by the @|SodObject| class. This message uses a nonstandard
+method combination which works like the standard combination, except that the
+\emph{default behaviour}, if there is no overriding method, is to initialize
+the instance's slots using the initializers defined in the class and its
+superclasses. This default behaviour may be invoked multiple times if some
+method calls on its @|next_method| more than once, unless some other method
+takes steps to prevent this.
+
+The recommended way to add new initialization behaviour is to define @|after|
+methods on the @|init| message. These will be run after the slot
+initializers have been applied, in reverse precedence order.
+
+Initialization is \emph{parametrized}, so the caller may select from a space
+of possible initial states for the new instance, or to inform the new
+instance about some other objects known to the caller. Specifically, the
+@|init| message accepts keyword arguments (\xref{sec:concepts.keywords})
+which can be defined and used by methods defined on it.
\subsubsection{Example}
The following is a simple function, with syntactic-sugar macro, which
allocate storage for an instance of a class, imprints and initializes it, and
returns a pointer to the new instance.
\begin{prog}
- void *make_instance(const SodClass *c) \\
+ void *make_instance(const SodClass *c, @|\dots|) \\
\{ \\ \ind
+ va_list ap;
void *p = malloc(c@->cls.initsz); \\
if (!p) return (0); \\
- c@->cls.imprint(p); \\
- c@->cls.init(p); \\
+ va_start(ap, c); \\
+ sod_initv(c, p, ap); \\
+ va_end(ap); \\
return (p); \- \\
\}
\\+
- \#define MAKE(cls) (cls *)make_instance(cls\#\#__class)
+ \#define MAKE(cls, keys) (cls *)make_instance(cls\#\#__class, keys)
\end{prog}