(usually) change its direct class, and the direct class of an object is not
affected by, for example, the static type of a pointer to it.
+
\subsection{Superclasses and inheritance}
\label{sec:concepts.classes.inherit}
then all the superclasses of $C$ must have distinct nicknames.
\end{itemize}
+
\subsection{Slots} \label{sec:concepts.classes.slots}
Each class defines a number of \emph{slots}. Much like a structure member, a
implementation of C89. Initializers will be evaluated once each time an
instance is initialized.
+
\subsection{C language integration} \label{sec:concepts.classes.c}
For each class~$C$, the Sod translator defines a C type, the \emph{class
For example, if @|MyClass| has the nickname @|mine|, and defines a slot @|x|
of type @|int|, then the simple function
\begin{prog}
- int get_x(MyClass *m) \{ return (m->mine.x); \}
+ int get_x(MyClass *m) \{ return (m@->mine.x); \}
\end{prog}
will extract the value of @|x| from an instance of @|MyClass|.
\begin{prog}
void *new_instance(const SodClass *c) \\
\{ \\ \ind
- void *p = malloc(c->cls.initsz); \\
+ void *p = malloc(c@->cls.initsz); \\
if (!p) return (0); \\
- c->cls.init(p); \\
+ c@->cls.init(p); \\
return (p); \- \\
\}
\end{prog}
method defined for a class $C$, the variable @|me|, of type pointer to class
type of $C$, refers to the receiving object.
+
\subsection{Effective methods and method combinations}
\label{sec:concepts.methods.combination}
\item if the message accepts a variable-length argument suffix then the
direct method must instead have a final argument of type @|va_list|.
\end{itemize}
-Primary and around methods must have the same return type as the message;
-before and after methods must return @|void| regardless of the message's
-return type.
+Primary and @|around| methods must have the same return type as the message;
+@|before| and @|after| methods must return @|void| regardless of the
+message's return type.
If there are no applicable primary methods then no effective method is
constructed: the vtables contain null pointers in place of pointers to method
specific such method, with respect to the class of the receiving object, is
invoked.
- Within the body of an around method, the variable @|next_method| is
+ Within the body of an @|around| method, the variable @|next_method| is
defined, having pointer-to-function type. The method may call this
function, as described below, any number of times.
- If there any remaining around methods, then @|next_method| invokes the next
- most specific such method, returning whichever value that method returns;
- otherwise the behaviour of @|next_method| is to invoke the before methods
- (if any), followed by the most specific primary method, followed by the
- around methods (if any), and to return whichever value was returned by the
- most specific primary method. That is, the behaviour of the least specific
- around method's @|next_method| function is exactly the behaviour that the
- effective method would have if there were no around methods.
+ If there any remaining @|around| methods, then @|next_method| invokes the
+ next most specific such method, returning whichever value that method
+ returns; otherwise the behaviour of @|next_method| is to invoke the before
+ methods (if any), followed by the most specific primary method, followed by
+ the @|around| methods (if any), and to return whichever value was returned
+ by the most specific primary method. That is, the behaviour of the least
+ specific @|around| method's @|next_method| function is exactly the
+ behaviour that the effective method would have if there were no @|around|
+ methods.
- The value returned by the most specific around method is the value returned
- by the effective method.
+ The value returned by the most specific @|around| method is the value
+ returned by the effective method.
\item If any applicable methods have the @|before| role, then they are all
invoked, starting with the most specific.
invoke the next most specific applicable primary method, and to return
whichever value that method returns.
- If there are no applicable around methods, then the value returned by the
- most specific primary method is the value returned by the effective method;
- otherwise the value returned by the most specific primary method is
- returned to the least specific around method, which called it via its own
- @|next_method| function.
+ If there are no applicable @|around| methods, then the value returned by
+ the most specific primary method is the value returned by the effective
+ method; otherwise the value returned by the most specific primary method is
+ returned to the least specific @|around| method, which called it via its
+ own @|next_method| function.
\item If any applicable methods have the @|after| role, then they are all
invoked, starting with the \emph{least} specific. (Hence, the most
- specific after method is invoked with the most `afterness'.)
+ specific @|after| method is invoked with the most `afterness'.)
\end{enumerate}
-A typical use for around methods is to set up the dynamic environment
-appropriately for the primary methods, e.g., by claiming a lock.
+A typical use for @|around| methods is to allow a base class to set up the
+dynamic environment appropriately for the primary methods of its subclasses,
+e.g., by claiming a lock, and restore it afterwards.
The @|next_method| function provided to methods with the @|primary| and
@|around| roles accepts the same arguments, and returns the same type, as the
each.
The aggregating method combinations accept the same four roles as the
-standard method combination, and around, before, and after methods work in
-the same way.
+standard method combination, and @|around|, @|before|, and @|after| methods
+work in the same way.
The aggregating method combinations provided are as follows.
\begin{description} \let\makelabel\code
\item[max] The message must return a scalar type. The applicable primary
methods are invoked in turn. The final result is the largest of the
individual values.
-\item[and] The message must return @|int|. The applicable primary methods
- are invoked in turn. If any method returns zero then the final result is
- zero and no further methods are invoked. If all of the applicable primary
- methods return nonzero, then the final result is a nonzero value.
-\item[or] The message must return @|int|. The applicable primary methods are
- invoked in turn. If any method returns nonzero then the final result is a
- nonzero value and no further methods are invoked. If all of the applicable
- primary methods return zero, then the final result is zero.
+\item[and] The message must return a scalar type. The applicable primary
+ methods are invoked in turn. If any method returns zero then the final
+ result is zero and no further methods are invoked. If all of the
+ applicable primary methods return nonzero, then the final result is the
+ result of the last primary method.
+\item[or] The message must return a scalar type. The applicable primary
+ methods are invoked in turn. If any method returns nonzero then the final
+ result is that nonzero value and no further methods are invoked. If all of
+ the applicable primary methods return zero, then the final result is zero.
\end{description}
There is also a @|custom| aggregating method combination, which is described