diff options
Diffstat (limited to 'doc/manual')
-rw-r--r-- | doc/manual/effects.txt | 4 | ||||
-rw-r--r-- | doc/manual/ffi.txt | 2 | ||||
-rw-r--r-- | doc/manual/generics.txt | 44 | ||||
-rw-r--r-- | doc/manual/lexing.txt | 4 | ||||
-rw-r--r-- | doc/manual/modules.txt | 10 | ||||
-rw-r--r-- | doc/manual/pragmas.txt | 22 | ||||
-rw-r--r-- | doc/manual/procs.txt | 8 | ||||
-rw-r--r-- | doc/manual/stmts.txt | 4 | ||||
-rw-r--r-- | doc/manual/templates.txt | 12 | ||||
-rw-r--r-- | doc/manual/trmacros.txt | 26 | ||||
-rw-r--r-- | doc/manual/type_bound_ops.txt | 10 | ||||
-rw-r--r-- | doc/manual/type_sections.txt | 16 | ||||
-rw-r--r-- | doc/manual/typedesc.txt | 8 | ||||
-rw-r--r-- | doc/manual/types.txt | 112 |
14 files changed, 141 insertions, 141 deletions
diff --git a/doc/manual/effects.txt b/doc/manual/effects.txt index 73934ab34..a79f6ea85 100644 --- a/doc/manual/effects.txt +++ b/doc/manual/effects.txt @@ -29,9 +29,9 @@ compatibility: .. code-block:: nim type - TCallback = proc (s: string) {.raises: [IOError].} + Callback = proc (s: string) {.raises: [IOError].} var - c: TCallback + c: Callback proc p(x: string) = raise newException(OSError, "OS") diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt index 0ad4ebba9..4a4e0316f 100644 --- a/doc/manual/ffi.txt +++ b/doc/manual/ffi.txt @@ -57,7 +57,7 @@ instructs the compiler to pass the type by value to procs: .. code-block:: nim type - TVector {.bycopy, pure.} = object + Vector {.bycopy, pure.} = object x, y, z: float diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt index 6f1b2ee0d..f3e7b7b4c 100644 --- a/doc/manual/generics.txt +++ b/doc/manual/generics.txt @@ -9,17 +9,17 @@ The following example shows a generic binary tree can be modelled: .. code-block:: nim type - TBinaryTree[T] = object # TBinaryTree is a generic type with + BinaryTreeObj[T] = object # BinaryTreeObj is a generic type with # with generic param ``T`` - le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil + le, ri: BinaryTree[T] # left and right subtrees; may be nil data: T # the data stored in a node - PBinaryTree[T] = ref TBinaryTree[T] # a shorthand for notational convenience + BinaryTree[T] = ref BinaryTreeObj[T] # a shorthand for notational convenience - proc newNode[T](data: T): PBinaryTree[T] = # constructor for a node + proc newNode[T](data: T): BinaryTree[T] = # constructor for a node new(result) result.data = data - proc add[T](root: var PBinaryTree[T], n: PBinaryTree[T]) = + proc add[T](root: var BinaryTree[T], n: BinaryTree[T]) = if root == nil: root = n else: @@ -40,7 +40,7 @@ The following example shows a generic binary tree can be modelled: return it = it.ri - iterator inorder[T](root: PBinaryTree[T]): T = + iterator inorder[T](root: BinaryTree[T]): T = # inorder traversal of a binary tree # recursive iterators are not yet implemented, so this does not work in # the current compiler! @@ -49,7 +49,7 @@ The following example shows a generic binary tree can be modelled: if root.ri != nil: yield inorder(root.ri) var - root: PBinaryTree[string] # instantiate a PBinaryTree with the type string + root: BinaryTree[string] # instantiate a BinaryTree with the type string add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and add(root, newNode("world")) # ``add`` for str in inorder(root): @@ -64,10 +64,10 @@ therefore very useful for type specialization within generic code: .. code-block:: nim type - TTable[TKey, TValue] = object - keys: seq[TKey] - values: seq[TValue] - when not (TKey is string): # nil value for strings used for optimization + Table[Key, Value] = object + keys: seq[Key] + values: seq[Value] + when not (Key is string): # nil value for strings used for optimization deletedKeys: seq[bool] @@ -127,9 +127,9 @@ more complex type classes: .. code-block:: nim # create a type class that will match all tuple and object types - type TRecordType = tuple or object + type RecordType = tuple or object - proc printFields(rec: TRecordType) = + proc printFields(rec: RecordType) = for key, value in fieldPairs(rec): echo key, " = ", value @@ -175,11 +175,11 @@ type parameters of the matched generic type. They can be easily accessed using the dot syntax: .. code-block:: nim - type TMatrix[T, Rows, Columns] = object + type Matrix[T, Rows, Columns] = object ... - proc `[]`(m: TMatrix, row, col: int): TMatrix.T = - m.data[col * high(TMatrix.Columns) + row] + proc `[]`(m: Matrix, row, col: int): Matrix.T = + m.data[col * high(Matrix.Columns) + row] Alternatively, the `type` operator can be used over the proc params for similar effect when anonymous or distinct type classes are used. @@ -195,7 +195,7 @@ type, this results in another more specific type class: # seq[T1] is the same as just `seq`, but T1 will be allowed to bind # to a single type, while the signature is being matched - TMatrix[Ordinal] # Any TMatrix instantiation using integer values + Matrix[Ordinal] # Any Matrix instantiation using integer values As seen in the previous example, in such instantiations, it's not necessary to supply all type parameters of the generic type, because any missing ones will @@ -292,18 +292,18 @@ at definition and the context at instantiation are considered: .. code-block:: nim type - TIndex = distinct int + Index = distinct int - proc `==` (a, b: TIndex): bool {.borrow.} + proc `==` (a, b: Index): bool {.borrow.} - var a = (0, 0.TIndex) - var b = (0, 0.TIndex) + var a = (0, 0.Index) + var b = (0, 0.Index) echo a == b # works! In the example the generic ``==`` for tuples (as defined in the system module) uses the ``==`` operators of the tuple's components. However, the ``==`` for -the ``TIndex`` type is defined *after* the ``==`` for tuples; yet the example +the ``Index`` type is defined *after* the ``==`` for tuples; yet the example compiles as the instantiation takes the currently defined symbols into account too. diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt index 4de7936a3..e2f006f04 100644 --- a/doc/manual/lexing.txt +++ b/doc/manual/lexing.txt @@ -261,9 +261,9 @@ A character is not an Unicode character but a single byte. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for this. Another reason is that Nim can thus support ``array[char, int]`` or -``set[char]`` efficiently as many algorithms rely on this feature. The `TRune` +``set[char]`` efficiently as many algorithms rely on this feature. The `Rune` type is used for Unicode characters, it can represent any Unicode character. -``TRune`` is declared in the `unicode module <unicode.html>`_. +``Rune`` is declared in the `unicode module <unicode.html>`_. Numerical constants diff --git a/doc/manual/modules.txt b/doc/manual/modules.txt index 4000597d0..70f6026b2 100644 --- a/doc/manual/modules.txt +++ b/doc/manual/modules.txt @@ -128,22 +128,22 @@ modules don't need to import a module's dependencies: .. code-block:: nim # module B - type TMyObject* = object + type MyObject* = object .. code-block:: nim # module A import B - export B.TMyObject + export B.MyObject - proc `$`*(x: TMyObject): string = "my object" + proc `$`*(x: MyObject): string = "my object" .. code-block:: nim # module C import A - # B.TMyObject has been imported implicitly here: - var x: TMyObject + # B.MyObject has been imported implicitly here: + var x: MyObject echo($x) diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 6bb1314cd..34428233f 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -89,12 +89,12 @@ collector to not consider objects of this type as part of a cycle: .. code-block:: nim type - PNode = ref TNode - TNode {.acyclic, final.} = object - left, right: PNode + Node = ref NodeObj + NodeObj {.acyclic, final.} = object + left, right: Node data: string -In the example a tree structure is declared with the ``TNode`` type. Note that +In the example a tree structure is declared with the ``Node`` type. Note that the type definition is recursive and the GC has to assume that objects of this type may form a cyclic graph. The ``acyclic`` pragma passes the information that this cannot happen to the GC. If the programmer uses the @@ -106,9 +106,9 @@ memory, but nothing worse happens. .. code-block:: nim type - PNode = acyclic ref TNode - TNode = object - left, right: PNode + Node = acyclic ref NodeObj + NodeObj = object + left, right: Node data: string @@ -129,13 +129,13 @@ structure: .. code-block:: nim type - TNodeKind = enum nkLeaf, nkInner - TNode {.final, shallow.} = object - case kind: TNodeKind + NodeKind = enum nkLeaf, nkInner + Node {.final, shallow.} = object + case kind: NodeKind of nkLeaf: strVal: string of nkInner: - children: seq[TNode] + children: seq[Node] pure pragma diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 2ebbe494d..a8a2d271d 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -121,21 +121,21 @@ different; for this a special setter syntax is needed: .. code-block:: nim type - TSocket* = object of TObject + Socket* = object of RootObj FHost: int # cannot be accessed from the outside of the module # the `F` prefix is a convention to avoid clashes since # the accessors are named `host` - proc `host=`*(s: var TSocket, value: int) {.inline.} = + proc `host=`*(s: var Socket, value: int) {.inline.} = ## setter of hostAddr s.FHost = value - proc host*(s: TSocket): int {.inline.} = + proc host*(s: Socket): int {.inline.} = ## getter of hostAddr s.FHost var - s: TSocket + s: Socket s.host = 34 # same as `host=`(s, 34) diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 6222624e4..5b1284872 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -118,11 +118,11 @@ initialized and does not rely on syntactic properties: .. code-block:: nim type - TMyObject = object {.requiresInit.} + MyObject = object {.requiresInit.} proc p() = # the following is valid: - var x: TMyObject + var x: MyObject if someCondition(): x = a() else: diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt index 64bf71a96..eeb907ce0 100644 --- a/doc/manual/templates.txt +++ b/doc/manual/templates.txt @@ -67,7 +67,7 @@ special ``:`` syntax: .. code-block:: nim template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = - var f: TFile + var f: File if open(f, fn, mode): try: actions @@ -140,12 +140,12 @@ shadowed by the same argument name even when fully qualified: # module 'm' type - TLev = enum + Lev = enum levA, levB var abclev = levB - template tstLev(abclev: TLev) = + template tstLev(abclev: Lev) = echo abclev, " ", m.abclev tstLev(levA) @@ -157,12 +157,12 @@ But the global symbol can properly be captured by a ``bind`` statement: # module 'm' type - TLev = enum + Lev = enum levA, levB var abclev = levB - template tstLev(abclev: TLev) = + template tstLev(abclev: Lev) = bind m.abclev echo abclev, " ", m.abclev @@ -202,7 +202,7 @@ template parameter, it is an inject'ed symbol: .. code-block:: nim template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = block: - var f: TFile # since 'f' is a template param, it's injected implicitly + var f: File # since 'f' is a template param, it's injected implicitly ... withFile(txt, "ttempl3.txt", fmWrite): diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt index 715c9f850..90d01e475 100644 --- a/doc/manual/trmacros.txt +++ b/doc/manual/trmacros.txt @@ -223,21 +223,21 @@ all the arguments, but also the matched operators in reverse polish notation: import macros type - TMatrix = object + Matrix = object dummy: int - proc `*`(a, b: TMatrix): TMatrix = discard - proc `+`(a, b: TMatrix): TMatrix = discard - proc `-`(a, b: TMatrix): TMatrix = discard - proc `$`(a: TMatrix): string = result = $a.dummy - proc mat21(): TMatrix = + proc `*`(a, b: Matrix): Matrix = discard + proc `+`(a, b: Matrix): Matrix = discard + proc `-`(a, b: Matrix): Matrix = discard + proc `$`(a: Matrix): string = result = $a.dummy + proc mat21(): Matrix = result.dummy = 21 - macro optM{ (`+`|`-`|`*`) ** a }(a: TMatrix): expr = + macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): expr = echo treeRepr(a) result = newCall(bindSym"mat21") - var x, y, z: TMatrix + var x, y, z: Matrix echo x + y * z - x @@ -267,7 +267,7 @@ parameter is of the type ``varargs`` it is treated specially and it can match template optWrite{ write(f, x) ((write|writeln){w})(f, y) - }(x, y: varargs[expr], f: TFile, w: expr) = + }(x, y: varargs[expr], f: File, w: expr) = w(f, x, y) @@ -294,7 +294,7 @@ The following example shows how some form of hoisting can be implemented: .. code-block:: nim import pegs - template optPeg{peg(pattern)}(pattern: string{lit}): TPeg = + template optPeg{peg(pattern)}(pattern: string{lit}): Peg = var gl {.global, gensym.} = peg(pattern) gl @@ -341,21 +341,21 @@ The ``call`` constraint is particularly useful to implement a move optimization for types that have copying semantics: .. code-block:: nim - proc `[]=`*(t: var TTable, key: string, val: string) = + proc `[]=`*(t: var Table, key: string, val: string) = ## puts a (key, value)-pair into `t`. The semantics of string require ## a copy here: let idx = findInsertionPosition(key) t[idx] = key t[idx] = val - proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) = + proc `[]=`*(t: var Table, key: string{call}, val: string{call}) = ## puts a (key, value)-pair into `t`. Optimized version that knows that ## the strings are unique and thus don't need to be copied: let idx = findInsertionPosition(key) shallowCopy t[idx], key shallowCopy t[idx], val - var t: TTable + var t: Table # overloading resolution ensures that the optimized []= is called here: t[f()] = g() diff --git a/doc/manual/type_bound_ops.txt b/doc/manual/type_bound_ops.txt index 64c6c325d..59d55a6cd 100644 --- a/doc/manual/type_bound_ops.txt +++ b/doc/manual/type_bound_ops.txt @@ -49,17 +49,17 @@ can then only be used in *destructible contexts* and as parameters: .. code-block:: nim type - TMyObj = object + MyObj = object x, y: int p: pointer - proc destroy(o: var TMyObj) {.override.} = + proc destroy(o: var MyObj) {.override.} = if o.p != nil: dealloc o.p - proc open: TMyObj = - result = TMyObj(x: 1, y: 2, p: alloc(3)) + proc open: MyObj = + result = MyObj(x: 1, y: 2, p: alloc(3)) - proc work(o: TMyObj) = + proc work(o: MyObj) = echo o.x # No destructor invoked here for 'o' as 'o' is a parameter. diff --git a/doc/manual/type_sections.txt b/doc/manual/type_sections.txt index 5413e896e..8420a0098 100644 --- a/doc/manual/type_sections.txt +++ b/doc/manual/type_sections.txt @@ -5,15 +5,15 @@ Example: .. code-block:: nim type # example demonstrating mutually recursive types - PNode = ref TNode # a traced pointer to a TNode - TNode = object - le, ri: PNode # left and right subtrees - sym: ref TSym # leaves contain a reference to a TSym + Node = ref NodeObj # a traced pointer to a NodeObj + NodeObj = object + le, ri: Node # left and right subtrees + sym: ref Sym # leaves contain a reference to a Sym - TSym = object # a symbol - name: string # the symbol's name - line: int # the line the symbol was declared in - code: PNode # the symbol's abstract syntax tree + Sym = object # a symbol + name: string # the symbol's name + line: int # the line the symbol was declared in + code: Node # the symbol's abstract syntax tree A type section begins with the ``type`` keyword. It contains multiple type definitions. A type definition binds a type to a name. Type definitions diff --git a/doc/manual/typedesc.txt b/doc/manual/typedesc.txt index d1d8bc87a..97ab18b56 100644 --- a/doc/manual/typedesc.txt +++ b/doc/manual/typedesc.txt @@ -10,7 +10,7 @@ As their name suggests, static params must be known at compile-time: .. code-block:: nim - proc precompiledRegex(pattern: static[string]): TRegEx = + proc precompiledRegex(pattern: static[string]): RegEx = var res {.global.} = re(pattern) return res @@ -35,7 +35,7 @@ predicate: # The following proc will be compiled once for each unique static # value and also once for the case handling all run-time values: - proc re(pattern: semistatic[string]): TRegEx = + proc re(pattern: semistatic[string]): RegEx = when isStatic(pattern): result = precompiledRegex(pattern) else: @@ -74,8 +74,8 @@ instantiation type using the param name: echo "allocating ", T.name new(result) - var n = TNode.new - var tree = new(TBinaryTree[int]) + var n = Node.new + var tree = new(BinaryTree[int]) When multiple typedesc params are present, they act like a distinct type class (i.e. they will bind freely to different types). To force a bind-once behavior diff --git a/doc/manual/types.txt b/doc/manual/types.txt index 94611bbbb..ff4b9044f 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -257,8 +257,8 @@ the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for this. Another reason is that Nim can support ``array[char, int]`` or ``set[char]`` efficiently as many algorithms rely on this feature. The -`TRune` type is used for Unicode characters, it can represent any Unicode -character. ``TRune`` is declared in the `unicode module <unicode.html>`_. +`Rune` type is used for Unicode characters, it can represent any Unicode +character. ``Rune`` is declared in the `unicode module <unicode.html>`_. @@ -591,38 +591,38 @@ An example: # This is an example how an abstract syntax tree could be modelled in Nim type - TNodeKind = enum # the different node types + NodeKind = enum # the different node types nkInt, # a leaf with an integer value nkFloat, # a leaf with a float value nkString, # a leaf with a string value nkAdd, # an addition nkSub, # a subtraction nkIf # an if statement - PNode = ref TNode - TNode = object - case kind: TNodeKind # the ``kind`` field is the discriminator + Node = ref NodeObj + NodeObj = object + case kind: NodeKind # the ``kind`` field is the discriminator of nkInt: intVal: int of nkFloat: floatVal: float of nkString: strVal: string of nkAdd, nkSub: - leftOp, rightOp: PNode + leftOp, rightOp: Node of nkIf: - condition, thenPart, elsePart: PNode + condition, thenPart, elsePart: Node # create a new case object: - var n = PNode(kind: nkIf, condition: nil) + var n = Node(kind: nkIf, condition: nil) # accessing n.thenPart is valid because the ``nkIf`` branch is active: - n.thenPart = PNode(kind: nkFloat, floatVal: 2.0) + n.thenPart = Node(kind: nkFloat, floatVal: 2.0) - # the following statement raises an `EInvalidField` exception, because + # the following statement raises an `FieldError` exception, because # n.kind's value does not fit and the ``nkString`` branch is not active: n.strVal = "" # invalid: would change the active object branch: n.kind = nkInt - var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4), - rightOp: PNode(kind: nkInt, intVal: 2)) + var x = Node(kind: nkAdd, leftOp: Node(kind: nkInt, intVal: 4), + rightOp: Node(kind: nkInt, intVal: 2)) # valid: does not change the active object branch: x.kind = nkSub @@ -672,13 +672,13 @@ dereferencing operations for reference types: .. code-block:: nim type - PNode = ref TNode - TNode = object - le, ri: PNode + Node = ref NodeObj + NodeObj = object + le, ri: Node data: int var - n: PNode + n: Node new(n) n.data = 9 # no need to write n[].data; in fact n[].data is highly discouraged! @@ -717,10 +717,10 @@ memory manually: .. code-block:: nim type - TData = tuple[x, y: int, s: string] + Data = tuple[x, y: int, s: string] - # allocate memory for TData on the heap: - var d = cast[ptr TData](alloc0(sizeof(TData))) + # allocate memory for Data on the heap: + var d = cast[ptr Data](alloc0(sizeof(Data))) # create a new string on the garbage collected heap: d.s = "abc" @@ -736,7 +736,7 @@ never be freed. The example also demonstrates two important features for low level programming: the ``sizeof`` proc returns the size of a type or value in bytes. The ``cast`` operator can circumvent the type system: the compiler is forced to treat the result of the ``alloc0`` call (which returns an untyped -pointer) as if it would have the type ``ptr TData``. Casting should only be +pointer) as if it would have the type ``ptr Data``. Casting should only be done if it is unavoidable: it breaks type safety and bugs can lead to mysterious crashes. @@ -855,13 +855,13 @@ Examples: .. code-block:: nim type - TOnMouseMove = proc (x, y: int) {.closure.} + OnMouseMove = proc (x, y: int) {.closure.} proc onMouseMove(mouseX, mouseY: int) = # has default calling convention echo "x: ", mouseX, " y: ", mouseY - proc setOnMouseMove(mouseMoveEvent: TOnMouseMove) = discard + proc setOnMouseMove(mouseMoveEvent: OnMouseMove) = discard # ok, 'onMouseMove' has the default calling convention, which is compatible # to 'closure': @@ -962,33 +962,33 @@ types are a perfect tool to model different currencies: .. code-block:: nim type - TDollar = distinct int - TEuro = distinct int + Dollar = distinct int + Euro = distinct int var - d: TDollar - e: TEuro + d: Dollar + e: Euro echo d + 12 - # Error: cannot add a number with no unit and a ``TDollar`` + # Error: cannot add a number with no unit and a ``Dollar`` -Unfortunately, ``d + 12.TDollar`` is not allowed either, -because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So +Unfortunately, ``d + 12.Dollar`` is not allowed either, +because ``+`` is defined for ``int`` (among others), not for ``Dollar``. So a ``+`` for dollars needs to be defined: .. code-block:: - proc `+` (x, y: TDollar): TDollar = - result = TDollar(int(x) + int(y)) + proc `+` (x, y: Dollar): Dollar = + result = Dollar(int(x) + int(y)) It does not make sense to multiply a dollar with a dollar, but with a number without unit; and the same holds for division: .. code-block:: - proc `*` (x: TDollar, y: int): TDollar = - result = TDollar(int(x) * y) + proc `*` (x: Dollar, y: int): Dollar = + result = Dollar(int(x) * y) - proc `*` (x: int, y: TDollar): TDollar = - result = TDollar(x * int(y)) + proc `*` (x: int, y: Dollar): Dollar = + result = Dollar(x * int(y)) proc `div` ... @@ -999,15 +999,15 @@ The pragma `borrow`:idx: has been designed to solve this problem; in principle it generates the above trivial implementations: .. code-block:: nim - proc `*` (x: TDollar, y: int): TDollar {.borrow.} - proc `*` (x: int, y: TDollar): TDollar {.borrow.} - proc `div` (x: TDollar, y: int): TDollar {.borrow.} + proc `*` (x: Dollar, y: int): Dollar {.borrow.} + proc `*` (x: int, y: Dollar): Dollar {.borrow.} + proc `div` (x: Dollar, y: int): Dollar {.borrow.} The ``borrow`` pragma makes the compiler use the same implementation as the proc that deals with the distinct type's base type, so no code is generated. -But it seems all this boilerplate code needs to be repeated for the ``TEuro`` +But it seems all this boilerplate code needs to be repeated for the ``Euro`` currency. This can be solved with templates_. .. code-block:: nim @@ -1037,8 +1037,8 @@ currency. This can be solved with templates_. multiplicative(typ, base) comparable(typ) - defineCurrency(TDollar, int) - defineCurrency(TEuro, int) + defineCurrency(Dollar, int) + defineCurrency(Euro, int) The borrow pragma can also be used to annotate the distinct type to allow @@ -1071,7 +1071,7 @@ values is vulnerable to the famous `SQL injection attack`:idx:\: .. code-block:: nim import strutils - proc query(db: TDbHandle, statement: string) = ... + proc query(db: DbHandle, statement: string) = ... var username: string @@ -1081,13 +1081,13 @@ values is vulnerable to the famous `SQL injection attack`:idx:\: This can be avoided by distinguishing strings that contain SQL from strings that don't. Distinct types provide a means to introduce a new string type -``TSQL`` that is incompatible with ``string``: +``SQL`` that is incompatible with ``string``: .. code-block:: nim type - TSQL = distinct string + SQL = distinct string - proc query(db: TDbHandle, statement: TSQL) = ... + proc query(db: DbHandle, statement: SQL) = ... var username: string @@ -1098,28 +1098,28 @@ that don't. Distinct types provide a means to introduce a new string type It is an essential property of abstract types that they **do not** imply a subtype relation between the abtract type and its base type. Explict type -conversions from ``string`` to ``TSQL`` are allowed: +conversions from ``string`` to ``SQL`` are allowed: .. code-block:: nim import strutils, sequtils - proc properQuote(s: string): TSQL = + proc properQuote(s: string): SQL = # quotes a string properly for an SQL statement - return TSQL(s) + return SQL(s) - proc `%` (frmt: TSQL, values: openarray[string]): TSQL = + proc `%` (frmt: SQL, values: openarray[string]): SQL = # quote each argument: - let v = values.mapIt(TSQL, properQuote(it)) + let v = values.mapIt(SQL, properQuote(it)) # we need a temporary type for the type conversion :-( - type TStrSeq = seq[string] + type StrSeq = seq[string] # call strutils.`%`: - result = TSQL(string(frmt) % TStrSeq(v)) + result = SQL(string(frmt) % StrSeq(v)) - db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username]) + db.query("SELECT FROM users WHERE name = '$1'".SQL % [username]) Now we have compile-time checking against SQL injection attacks. Since -``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice -looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually +``"".SQL`` is transformed to ``SQL("")`` no new syntax is needed for nice +looking ``SQL`` string literals. The hypothetical ``SQL`` type actually exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of modules like `db_sqlite <db_sqlite.html>`_. |