| 1 | %%% -*-latex-*- |
| 2 | %%% |
| 3 | %%% Tutorial information |
| 4 | %%% |
| 5 | %%% (c) 2009 Straylight/Edgeware |
| 6 | %%% |
| 7 | |
| 8 | %%%----- Licensing notice --------------------------------------------------- |
| 9 | %%% |
| 10 | %%% This file is part of the Simple Object Definition system. |
| 11 | %%% |
| 12 | %%% SOD is free software; you can redistribute it and/or modify |
| 13 | %%% it under the terms of the GNU General Public License as published by |
| 14 | %%% the Free Software Foundation; either version 2 of the License, or |
| 15 | %%% (at your option) any later version. |
| 16 | %%% |
| 17 | %%% SOD is distributed in the hope that it will be useful, |
| 18 | %%% but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | %%% GNU General Public License for more details. |
| 21 | %%% |
| 22 | %%% You should have received a copy of the GNU General Public License |
| 23 | %%% along with SOD; if not, write to the Free Software Foundation, |
| 24 | %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 25 | |
| 26 | \chapter{Tutorial} \label{ch:tutorial} |
| 27 | |
| 28 | This chapter provides a tutorial introduction to the Sod object system. It |
| 29 | intentionally misses out nitty-gritty details. If you want those, the |
| 30 | remaining chapters provide a complete reference to Sod. |
| 31 | |
| 32 | The author isn't terribly good at writing tutorial-style documentation. |
| 33 | You'll have to bear with him. If you think you can do a better job, I'm sure |
| 34 | that he'll be grateful for your contribution. |
| 35 | |
| 36 | %%%-------------------------------------------------------------------------- |
| 37 | \section{Introduction} \label{sec:tutorial.intro} |
| 38 | |
| 39 | Sod is an object system for the C~programming language. Because it doesn't |
| 40 | have enough already. Actually, that's not right: it's got plenty already. |
| 41 | But Sod is a Sensible Object Design, and C doesn't have any of those. |
| 42 | |
| 43 | What does that mean when the author's not off on one of his tirades? It |
| 44 | means that is has the following features. |
| 45 | \begin{itemize} |
| 46 | \item It has a \emph{minimal runtime system}. Sod isn't likely to interfere |
| 47 | with other language runtimes or be difficult to deal with from a practical |
| 48 | point of view. |
| 49 | \item It provides \emph{multiple inheritance}. Rather than having a single |
| 50 | superclass, Sod allows a class to specify any number of superclasses. |
| 51 | Moreover, it implements multiple inheritance using \emph{superclass |
| 52 | linearization}, which means that it's not a nightmare to deal with. |
| 53 | \item It provides multiple \emph{method rĂ´les}, including `before', `after' |
| 54 | and `around' methods, which makes constructing object protocols rather more |
| 55 | straightforward. |
| 56 | \item It provides a number of \emph{method combinations}. For those coming |
| 57 | from languages other than Lisp, a method combination is a rule for deciding |
| 58 | how to invoke the various methods which might be used to respond to a |
| 59 | message. (This might still sound like a strange idea. We'll deal with it |
| 60 | in detail later.) |
| 61 | \item It allows \emph{user-defined method combinations}. It does a whole lot |
| 62 | more: there's an entire translation-time \emph{meta-object protocol}, so |
| 63 | that extensions can modify many different aspects of the object system. |
| 64 | The downside is that you have to learn Common Lisp and roll up your sleeves |
| 65 | if you want to do any of this. |
| 66 | \end{itemize} |
| 67 | There's a good chance that half of that didn't mean anything to you. Bear |
| 68 | with me, though, because we'll explain it all eventually. |
| 69 | |
| 70 | \subsection{Building programs with Sod} \label{sec:tutorial.intro.build} |
| 71 | |
| 72 | Sod is basically a fancy preprocessor, in the same vein as Lex and Yacc. It |
| 73 | reads source files written in a vaguely C-like language. It produces output |
| 74 | files which are actually C code (both header files and standalone sources), |
| 75 | and which contain chunks of the input files verbatim. |
| 76 | |
| 77 | The main consequences of this are as follows. |
| 78 | \begin{itemize} |
| 79 | \item The output is completely portable between different machines and |
| 80 | compilers. If you're preparing a source distribution for general release, |
| 81 | it's probably a good idea to provide the generated C~source as well as your |
| 82 | Sod sources. |
| 83 | \item Sod hasn't made any attempt to improve C's syntax. It's just as |
| 84 | hostile to object-oriented programming as it ever was. This means that |
| 85 | you'll end up writing ugly things like |
| 86 | \begin{prog} |
| 87 | thing@->_vt@->foo.frob(thing, mumble); |
| 88 | \end{prog} |
| 89 | fairly frequently. This can be made somewhat less painful using macros, |
| 90 | but we're basically stuck with C. The upside is that you know exactly what |
| 91 | you're getting. A common complaint about \Cplusplus\ is that it has a |
| 92 | tendency to hide arbitrarily complicated runtime behaviour behind |
| 93 | apparently innocent syntax: you don't get any of that with Sod. Some |
| 94 | people might even think this is a benefit. |
| 95 | \end{itemize} |
| 96 | Of course, this means that your build system needs to become more |
| 97 | complicated. If you use \man{make}{1}, then something like |
| 98 | \begin{prog} |
| 99 | SOD = sod \\+ |
| 100 | |
| 101 | .SUFFIXES: .sod .c .h \\ |
| 102 | .sod.c:; \$(SOD) -tc \$< \\ |
| 103 | .sod.h:; \$(SOD) -th \$< |
| 104 | \end{prog} |
| 105 | ought to do the job. |
| 106 | |
| 107 | %%%-------------------------------------------------------------------------- |
| 108 | \section{A traditional trivial introduction} |
| 109 | |
| 110 | The following is a simple Sod input file. |
| 111 | \begin{prog} |
| 112 | /* -*-sod-*- */ \\+ |
| 113 | |
| 114 | code c : includes \{ \\ |
| 115 | \#include "greeter.h" \\ |
| 116 | \} \\+ |
| 117 | |
| 118 | code h : includes \{ \\ |
| 119 | \#include <stdio.h> \\ |
| 120 | \#include <sod/sod.h> \\ |
| 121 | \} \\+ |
| 122 | |
| 123 | class Greeter : SodObject \{ \\ \ind |
| 124 | void greet(FILE *fp) \{ \\ \ind |
| 125 | fputs("Hello, world!\textbackslash n", fp); \-\\ |
| 126 | \} \-\\ |
| 127 | \} |
| 128 | \end{prog} |
| 129 | Save it as @"greeter.sod", and run |
| 130 | \begin{prog} |
| 131 | sod --gc --gh greeter |
| 132 | \end{prog} |
| 133 | This will create files @"greeter.c" and @"greeter.h" in the current |
| 134 | directory. Here's how we might use such a simple thing. |
| 135 | \begin{prog} |
| 136 | \#include "greeter.h" \\+ |
| 137 | |
| 138 | int main(void) \\ |
| 139 | \{ \\ \ind |
| 140 | SOD_DECL(Greeter, g); \\+ |
| 141 | |
| 142 | Greeter_greet(g, stdout); \\ |
| 143 | return (0); \-\\ |
| 144 | \} |
| 145 | \end{prog} |
| 146 | Compare this to the traditional |
| 147 | \begin{prog} |
| 148 | \#include <stdio.h> \\+ |
| 149 | |
| 150 | int main(void) \\ \ind |
| 151 | \{ fputs("Hello, world@\\n", stdout); return (0); \} |
| 152 | \end{prog} |
| 153 | and I'm sure you'll appreciate the benefits of using Sod already -- mostly to |
| 154 | do with finger exercise. Trust me, it gets more useful. |
| 155 | |
| 156 | The @".sod" file was almost comprehensible. There are two important parts to |
| 157 | it (after the comment which tells Emacs how to cope with it). |
| 158 | |
| 159 | The first part consists of the two @"code" stanzas. Both of them define |
| 160 | gobbets of raw C code to copy into output files. The first one, @"code~: |
| 161 | c"~\ldots, says that |
| 162 | \begin{prog} |
| 163 | \#include "greeter.h" |
| 164 | \end{prog} |
| 165 | needs to appear in the generated @|greeter.c| file; the second says that |
| 166 | \begin{prog} |
| 167 | \#include <stdio.h> \\ |
| 168 | \#include <sod/sod.h> |
| 169 | \end{prog} |
| 170 | needs to appear in the header file @|greeter.h|. The generated C files need |
| 171 | to get declarations for external types and functions (e.g., @"FILE" and |
| 172 | @"fputs") from somewhere, and the generated @".c" file will need the |
| 173 | declarations from the corresponding @".h" file. Sod takes a very simple |
| 174 | approach to all of this: it expects you, the programmer, to deal with it. |
| 175 | |
| 176 | The basic syntax for @"code" stanzas is |
| 177 | \begin{prog} |
| 178 | code @<file-label> : @<section> \{ \\ \ind |
| 179 | @<code> \-\\ |
| 180 | \} |
| 181 | \end{prog} |
| 182 | The @<file-label> is either @"c" or @"h", and says which output file the code |
| 183 | wants to be written to. The @<section> is a name which explains where in the |
| 184 | output file to place the code. The @"includes" section is the usual choice: |
| 185 | it's the `right' place for @`\#include' directives and similar declarations. |
| 186 | |
| 187 | The remaining part, the `meat' of the file, defines a class called |
| 188 | @"greeter". The class can respond to a single message, named @"greet", and |
| 189 | in response, it writes a traditional greeting to the file passed in with the |
| 190 | message. |
| 191 | |
| 192 | So far, so good. The C code, which we thought we understood, contains some |
| 193 | bizarre looking runes. Let's take it one step at a time. |
| 194 | \begin{prog} |
| 195 | struct Greeter__ilayout g_obj; |
| 196 | \end{prog} |
| 197 | allocates space for an instance of class @"Greeter". We're not going to use |
| 198 | this space directly. Instead, we do this frightening looking thing. |
| 199 | \begin{prog} |
| 200 | Greeter *g = Greeter__class@->cls.init(\&g_obj); |
| 201 | \end{prog} |
| 202 | Taking it slowly: @"Greeter__class" is a pointer to the object that |
| 203 | represents our class @"Greeter". This object contains a member, named |
| 204 | @"cls.init", which points to a function whose job is to turn uninitialized |
| 205 | storage space into working instances of the class. It returns a pointer to |
| 206 | the instance, which we use in preference to grovelling about in the |
| 207 | @"ilayout" structure. |
| 208 | |
| 209 | Having done this, we `send the instance a message': |
| 210 | \begin{prog} |
| 211 | g@->_vt@->greeter.greet(g, stdout); |
| 212 | \end{prog} |
| 213 | This looks horrific, and seems to repeat itself quite unnecessarily. The |
| 214 | first @"g" is the recipient of our `message'. The second is indeed a copy of |
| 215 | the first: we have to tell it who it is. (Sod doesn't extend C's syntax, so |
| 216 | this is the sort of thing we just have to put up with.) The lowercase |
| 217 | @"greeter" is our class's `nickname': we didn't choose one explicitly, so Sod |
| 218 | picked one by forcing the classname to lowercase. |
| 219 | |
| 220 | %%%----- That's all, folks -------------------------------------------------- |
| 221 | |
| 222 | %%% Local variables: |
| 223 | %%% mode: LaTeX |
| 224 | %%% TeX-master: "sod.tex" |
| 225 | %%% TeX-PDF-mode: t |
| 226 | %%% End: |