|
1 |
| -* defclass-std |
2 |
| - [[https://travis-ci.org/EuAndreh/defclass-std][https://travis-ci.org/EuAndreh/defclass-std.svg?branch=master]] |
3 |
| - [[https://coveralls.io/r/EuAndreh/defclass-std][https://coveralls.io/repos/EuAndreh/defclass-std/badge.svg?branch=master]] |
| 1 | +defclass-std |
| 2 | +============ |
4 | 3 |
|
5 |
| - Most times, when sketching out a new class, I often commit lots of typos and forget to add an =:initform=. |
| 4 | +[](https://travis-ci.org/EuAndreh/defclass-std) |
| 5 | +[](https://coveralls.io/r/EuAndreh/defclass-std?branch=master) |
6 | 6 |
|
7 |
| - Also, the throw away class designed in the beginning may thrive and stay the same. If only there was a way to overcome these problems... There is! |
| 7 | +Most times, when sketching out a new class, I often commit lots of typos and forget to add an `:initform`. |
8 | 8 |
|
9 |
| - This simple macro atempts to give a very DRY and succint interface to the common =DEFCLASS= form. The goal is to offer most of the capabilities of a normal =DEFCLASS=, only in a more compact way. |
| 9 | +Also, the throw away class designed in the beginning may thrive and stay the same. If only there was a way to overcome these problems... There is! |
10 | 10 |
|
11 |
| - Everything compiles down to =DEFCLASS=. |
12 |
| -** Usage |
13 |
| -#+BEGIN_SRC lisp |
| 11 | +This simple macro atempts to give a very DRY and succint interface to the common `DEFCLASS` form. The goal is to offer most of the capabilities of a normal `DEFCLASS`, only in a more compact way. |
| 12 | + |
| 13 | +Everything compiles down to `DEFCLASS`. |
| 14 | + |
| 15 | +Usage |
| 16 | +----- |
| 17 | + |
| 18 | +```lisp |
14 | 19 | * (ql:quickload :defclass-std)
|
15 | 20 | ; => (:DEFCLASS-STD)
|
16 | 21 | * (import 'defclass-std:defclass/std)
|
17 | 22 | ; => T
|
18 |
| -#+END_SRC |
| 23 | +``` |
19 | 24 |
|
20 |
| - A simple class defined with =DEFCLASS/STD= looks like this: |
21 |
| -#+BEGIN_SRC |
| 25 | +A simple class defined with `DEFCLASS/STD` looks like this: |
| 26 | +```lisp |
22 | 27 | (defclass/std example ()
|
23 | 28 | ((slot1 slot2 slot3)))
|
24 | 29 |
|
|
28 | 33 | ((SLOT1 :ACCESSOR SLOT1 :INITARG :SLOT1 :INITFORM NIL)
|
29 | 34 | (SLOT2 :ACCESSOR SLOT2 :INITARG :SLOT2 :INITFORM NIL)
|
30 | 35 | (SLOT3 :ACCESSOR SLOT3 :INITARG :SLOT3 :INITFORM NIL)))
|
31 |
| -#+END_SRC |
| 36 | +``` |
32 | 37 | As you can see, by default, the macro adds three options:
|
33 |
| - 1. =:accessor= + the name of the slot |
34 |
| - 2. =:initarg= + the name of the slot |
35 |
| - 3. =:initform nil= |
| 38 | + 1. `:accessor` + the name of the slot |
| 39 | + 2. `:initarg` + the name of the slot |
| 40 | + 3. `:initform nil` |
36 | 41 |
|
37 |
| - If you want to change the =:initform= value, you can use the =:std= option: |
38 |
| -#+BEGIN_SRC lisp |
| 42 | + If you want to change the `:initform` value, you can use the `:std` option: |
| 43 | +```lisp |
39 | 44 | (defclass std-test ()
|
40 | 45 | ((slot :std 1)))
|
41 | 46 |
|
42 | 47 | ; expands to:
|
43 | 48 |
|
44 | 49 | (DEFCLASS STD-TEST ()
|
45 | 50 | ((SLOT :ACCESSOR SLOT :INITARG :SLOT :INITFORM 1)))
|
46 |
| -#+END_SRC |
| 51 | +``` |
47 | 52 |
|
48 |
| - If you want to omit the =:initform= option, you have two ways: |
49 |
| - 1. Use =:std :unbound= explicitly |
50 |
| - 2. Change the value of =*default-std*=. By default it is set to =T=, so, when the =:std= option is omitted, =:initform= is set to nil. When =*default-std*= is set to nil, =:initform= is omitted when =:std= is omitted. |
51 |
| -#+BEGIN_SRC lisp |
| 53 | + If you want to omit the `:initform` option, you have two ways: |
| 54 | + 1. Use `:std :unbound` explicitly |
| 55 | + 2. Change the value of `*default-std*`. By default it is set to `T`, so, when the `:std` option is omitted, `:initform` is set to nil. When `*default-std*` is set to nil, `:initform` is omitted when `:std` is omitted. |
| 56 | +```lisp |
52 | 57 | (defclass/std omit-std ()
|
53 | 58 | ((slot :std :unbound)))
|
54 | 59 |
|
|
62 | 67 |
|
63 | 68 | (DEFCLASS OMIT-STD ()
|
64 | 69 | ((SLOT :ACCESSOR SLOT :INITARG :SLOT)))
|
65 |
| -#+END_SRC |
| 70 | +``` |
66 | 71 |
|
67 |
| - =:a=, =:i=, =:r= and =:w= are connected: when all of them are omitted, =:a= and =:i= are inserted by default. |
| 72 | + `:a`, `:i`, `:r` and `:w` are connected: when all of them are omitted, `:a` and `:i` are inserted by default. |
68 | 73 |
|
69 |
| - =:a= stands for =:accessor=, =:i= stands for =:initarg=, =:r= stands for =:reader= and =:w= stands for =:writer=. |
| 74 | + `:a` stands for `:accessor`, `:i` stands for `:initarg`, `:r` stands for `:reader` and `:w` stands for `:writer`. |
70 | 75 |
|
71 |
| - If any of those is present, the default (=:a= and =:i=) is omitted. |
72 |
| -#+BEGIN_SRC lisp |
| 76 | + If any of those is present, the default (`:a` and `:i`) is omitted. |
| 77 | +```lisp |
73 | 78 | (defclass/std airw ()
|
74 | 79 | ((slot1 slot2)
|
75 | 80 | (slot3 slot4 :r)
|
|
87 | 92 | (SLOT5 :WRITER SLOT5 :INITFORM NIL)
|
88 | 93 | (SLOT6 :ACCESSOR SLOT6 :INITFORM NIL)
|
89 | 94 | (SLOT7 :READER SLOT7 :INITARG :SLOT7 :INITFORM NIL)))
|
90 |
| -#+END_SRC |
91 |
| - Note that slot7 has an =:ri= option. That's just =:r= and =:i= together. |
| 95 | +``` |
| 96 | + Note that slot7 has an `:ri` option. That's just `:r` and `:i` together. |
92 | 97 |
|
93 |
| - If you want to use =:r= and =:w= together, use =:a= instead, or you'll get an error. The same stands for =:a= + =:r= and =:a= + =:w=. |
| 98 | + If you want to use `:r` and `:w` together, use `:a` instead, or you'll get an error. The same stands for `:a` + `:r` and `:a` + `:w`. |
94 | 99 |
|
95 |
| - You can choose to add the class name as a prefix for the acessor/reader/writer function. Just put =:with= or =:with-prefix= option. |
| 100 | + You can choose to add the class name as a prefix for the acessor/reader/writer function. Just put `:with` or `:with-prefix` option. |
96 | 101 |
|
97 |
| -#+BEGIN_SRC lisp |
| 102 | +```lisp |
98 | 103 | (defclass/std example ()
|
99 | 104 | ((slot1 :with)
|
100 | 105 | (slot2)))
|
|
104 | 109 | (DEFCLASS WITH ()
|
105 | 110 | ((SLOT1 :ACCESSOR EXAMPLE-SLOT1 :INITARG :SLOT1 :INITFORM NIL)
|
106 | 111 | (SLOT2 :ACCESSOR SLOT2 :INITARG :SLOT2 :INITFORM NIL)))
|
107 |
| -#+END_SRC |
| 112 | +``` |
108 | 113 |
|
109 |
| - To make a slot static (class-allocated), use =:@@= or =:static=. |
| 114 | + To make a slot static (class-allocated), use `:@@` or `:static`. |
110 | 115 |
|
111 |
| - To declare the type of a slot or to add documentation to a slot, use =:type= and =:doc=, respectively. |
| 116 | + To declare the type of a slot or to add documentation to a slot, use `:type` and `:doc`, respectively. |
112 | 117 |
|
113 |
| - For real quick, concise, dense and standard class definitions, use =CLASS/STD=: |
114 |
| -#+BEGIN_SRC lisp |
| 118 | + For real quick, concise, dense and standard class definitions, use `CLASS/STD`: |
| 119 | +```lisp |
115 | 120 | (class/std example slot1 slot2 slot3)
|
116 | 121 |
|
117 | 122 | ; which expands to:
|
|
125 | 130 | ((SLOT1 :ACCESSOR SLOT1 :INITARG :SLOT1 :INITFORM NIL)
|
126 | 131 | (SLOT2 :ACCESSOR SLOT2 :INITARG :SLOT2 :INITFORM NIL)
|
127 | 132 | (SLOT3 :ACCESSOR SLOT3 :INITARG :SLOT3 :INITFORM NIL)))
|
128 |
| -#+END_SRC |
| 133 | +``` |
129 | 134 |
|
130 |
| - You can also add the prefix by default by changing the value of the =*with-prefix*= special variable (defaults to =nil=): |
131 |
| -#+BEGIN_SRC lisp |
| 135 | + You can also add the prefix by default by changing the value of the `*with-prefix*` special variable (defaults to `nil`): |
| 136 | +```lisp |
132 | 137 | (eval-when (:compile-toplevel :load-toplevel :execute)
|
133 | 138 | (setf *with-prefix* t))
|
134 | 139 | (defclass/std pre ()
|
|
138 | 143 |
|
139 | 144 | (DEFCLASS PRE ()
|
140 | 145 | ((FIX :ACCESSOR PRE-FIX :INITARG :FIX)))
|
141 |
| -#+END_SRC |
| 146 | +``` |
142 | 147 |
|
143 | 148 | Unknown keywords are left intact:
|
144 |
| -#+BEGIN_SRC lisp |
| 149 | +```lisp |
145 | 150 | (defclass/std unknown ()
|
146 | 151 | ((slot :unknown :keywords)))
|
147 | 152 |
|
|
160 | 165 |
|
161 | 166 | (DEFCLASS UNKNOWN ()
|
162 | 167 | ((SLOT :WRITER SLOT :INITARG :SLOT :INITFORM NIL :KEYWORDS :UNKNOWN)))
|
163 |
| -#+END_SRC |
| 168 | +``` |
164 | 169 | ** Examples:
|
165 |
| -#+BEGIN_SRC lisp |
| 170 | +```lisp |
166 | 171 | (defclass/std computer (gadget)
|
167 | 172 | ((screen mouse keyboard :a :type string :with-prefix)
|
168 | 173 | (bluetooth touchpad :wi)
|
|
183 | 188 | (PLACE :READER COMPUTER-PLACE :INITFORM NIL :ALLOCATION :CLASS
|
184 | 189 | :DOCUMENTATION "Where it is")
|
185 | 190 | (OWNER :WRITER OWNER :INITFORM "Me" :ALLOCATION :CLASS)))
|
186 |
| -#+END_SRC |
| 191 | +``` |
187 | 192 |
|
188 | 193 | Real life examples:
|
189 | 194 |
|
190 | 195 | From [[https://github.com/AccelerationNet/cl-inflector/blob/master/langs.lisp][cl-inflector]]:
|
191 |
| -#+BEGIN_SRC lisp |
| 196 | +```lisp |
192 | 197 | (defclass language ()
|
193 | 198 | ((name :accessor name :initarg :name :initform nil)
|
194 | 199 | (plurals :accessor plurals :initarg :plurals :initform nil)
|
|
204 | 209 | ; or, using CLASS/STD:
|
205 | 210 |
|
206 | 211 | (class/std language name plurals singulars uncountables irregulars)
|
207 |
| -#+END_SRC |
| 212 | +``` |
208 | 213 | From [[https://github.com/fukamachi/clack/blob/9804d0b57350032ebdcf8539bae376b5528ac1f6/src/core/handler.lisp][clack]]:
|
209 |
| -#+BEGIN_SRC lisp |
| 214 | +```lisp |
210 | 215 | (defclass <handler> ()
|
211 | 216 | ((server-name :type keyword
|
212 | 217 | :initarg :server-name
|
|
218 | 223 | (defclass/std language ()
|
219 | 224 | ((server-name :type keyword)
|
220 | 225 | (acceptor)))
|
221 |
| -#+END_SRC |
| 226 | +``` |
222 | 227 | From [[https://github.com/archimag/restas/blob/3e37f868141c785d2468fab342d57cca2e2a40dd/src/route.lisp][RESTAS]]:
|
223 |
| -#+BEGIN_SRC lisp |
| 228 | +```lisp |
224 | 229 | (defclass route (routes:route)
|
225 | 230 | ((symbol :initarg :symbol :reader route-symbol)
|
226 | 231 | (module :initarg :module :initform nil :reader route-module)
|
|
240 | 245 | headers variables additional-variables :ri)
|
241 | 246 | (render-method :i :std #'identity)
|
242 | 247 | (header :ir)))
|
243 |
| -#+END_SRC |
| 248 | +``` |
244 | 249 | From [[http://common-lisp.net/project/defclass-star/configuration.lisp.html][defclass-star example]]:
|
245 |
| -#+BEGIN_SRC lisp |
| 250 | +```lisp |
246 | 251 | (defclass configuration ()
|
247 | 252 | ((package-name :type symbol :initarg :package-name :accessor package-name-of)
|
248 | 253 | (package-nicknames :initform '() :initarg :package-nicknames :accessor package-nicknames-of)
|
|
313 | 318 | :type (or (function (string)) symbol))
|
314 | 319 | (temp-directory :std (make-pathname :directory "/tmp"))
|
315 | 320 | (working-directory :std *default-pathname-defaults*)))
|
316 |
| -#+END_SRC |
| 321 | +``` |
317 | 322 | From [[https://github.com/jd/cl-hue/blob/master/cl-hue.lisp][cl-hue]]:
|
318 |
| -#+BEGIN_SRC lisp |
| 323 | +```lisp |
319 | 324 | (defclass light ()
|
320 | 325 | ((bridge :initarg :bridge :accessor light-bridge)
|
321 | 326 | (number :initarg :number :accessor light-number)
|
|
354 | 359 | (class/std light
|
355 | 360 | bridge number type name modelid uniqueid swversion pointsymbol on brightness
|
356 | 361 | hue saturation xy ct alert effect colormode reachable)
|
357 |
| -#+END_SRC |
| 362 | +``` |
358 | 363 |
|
359 |
| - There's a shortcut to setup a basic printing behaviour of a class, using =printing-unreadably=: |
360 |
| -#+BEGIN_SRC lisp |
| 364 | + There's a shortcut to setup a basic printing behaviour of a class, using `printing-unreadably`: |
| 365 | +```lisp |
361 | 366 | (printing-unreadably (field2 field3) (class/std myclass field1 field2 field3))
|
362 |
| -#+END_SRC |
| 367 | +``` |
363 | 368 | ** Dependencies
|
364 | 369 | This project depends only on the [[http://common-lisp.net/project/anaphora/][Anaphora]] library. The test package uses the [[github.com/fukamachi/prove][prove]] test library.
|
365 | 370 |
|
|
373 | 378 | This library is tested under SBCL, CCL and CLISP Common Lisp implementations.
|
374 | 379 |
|
375 | 380 | To run all the defined tests, use:
|
376 |
| -#+BEGIN_SRC lisp |
| 381 | +```lisp |
377 | 382 | * (asdf:test-system :defclass-std)
|
378 | 383 | ; prints lots of stuff...
|
379 | 384 | ; => T
|
380 |
| -#+END_SRC |
| 385 | +``` |
381 | 386 | Tests are also ran with [[https://travis-ci.org/EuAndreh/defclass-std][Travis CI]] using [[https://github.com/luismbo/cl-travis][cl-travis]] and [[https://github.com/KeenS/CIM][CIM]]. Check it out!
|
382 | 387 |
|
383 | 388 | ** Authors
|
|
388 | 393 | ** License
|
389 | 394 |
|
390 | 395 | Licensed under the LLGPL License.
|
| 396 | + |
0 commit comments