| 1 | = Cues = |
| 2 | |
| 3 | cue: a signal for action |
| 4 | |
| 5 | cue: a thing said or done that serves as a signal to an actor or other performer to enter |
| 6 | or to begin their speech or performance. |
| 7 | |
| 8 | |
| 9 | The '''cue''' keyword is used on some selected methods to indicate to the compiler that these methods |
| 10 | are special, implement a 'special' behaviour or concept and will be treated specially to the system. |
| 11 | |
| 12 | Cues supported include (or will include): |
| 13 | |
| 14 | * Initializer - cue init |
| 15 | |
| 16 | * Destructor (destruction cleanup/Finalizer) - cue finalize |
| 17 | |
| 18 | * Calculate an objects !HashCode - cue hash as int |
| 19 | |
| 20 | * Determine comparison operation - cue compare(other) as int |
| 21 | |
| 22 | * Determine object equality - cue equals(other) as int |
| 23 | |
| 24 | * Implement enumeration/iteration capability - cue enumerate as T* |
| 25 | |
| 26 | * Others may be added as needed |
| 27 | |
| 28 | == Links == |
| 29 | See [http://cobra-language.com/forums/viewtopic.php?f=4&t=213 Discussion Posting "Cue"] |
| 30 | |
| 31 | == Grammar == |
| 32 | # as for method definition but 'cue' replaces 'def' |
| 33 | {{{ |
| 34 | cue <methodName> [as <returnType>] [is <AccessModifiers>] |
| 35 | [has <Attributes>] |
| 36 | [<DocString>] |
| 37 | |
| 38 | cue <methodName>(<paramList>) [as <returnType>] [is <AccessModifiers>] |
| 39 | [has <Attributes>] |
| 40 | [<DocString>] |
| 41 | }}} |
| 42 | |
| 43 | |
| 44 | == Discussion == |
| 45 | |
| 46 | Language systems generally have special hooks at the object level for various purposes such as |
| 47 | comparisons, hash codes, enumeration, object construction, initialization and destruction |
| 48 | Different languages use differing conventions and names for much the same ideas. |
| 49 | |
| 50 | The original approach used the C#, VB, .Net naming except that constructors are done through "def init" |
| 51 | which had the unfortunate consequence of conflicting with some third party libraries |
| 52 | leading to some hacks in the compiler. Purportedly that approach also could not be |
| 53 | extended to other backends (such as JVM) as they dont use the same exact method names as .NET. |
| 54 | |
| 55 | The solution adopted was to introduce a new keyword '''cue''' used (instead of '''def''') on methods |
| 56 | that have or may have a special use or meaning and will be translated to the correct voodoo for |
| 57 | whatever platform you're on (.NET, JVM, etc.) |
| 58 | |
| 59 | Cues have some special rules about them, both in general and specific to particular cues: |
| 60 | |
| 61 | * Cue declarations are exempt from needing "is override" on them. |
| 62 | |
| 63 | * Most cues cannot be directly invoked external to the cue. |
| 64 | Normally however there is a canonical way in cobra to invoke the 'cued' capability or it |
| 65 | is invoked invisibly for you in the correct circumstances (hashcode)[[br]] |
| 66 | For example [[br]] |
| 67 | "a = !ClassName(args)" is the canonical way to construct and invoke an initializer [[br]] |
| 68 | "a == b" is the canonical way to compare objects for equality, and [[br]] |
| 69 | "for a in collection" is the canonical way to enumerate through the elements of a collection. |
| 70 | |
| 71 | * One exception to "do not invoke cues directly" is that *within* the declaration of a cue, |
| 72 | you can invoke it for purposes of implementation (e.g., base.init, .init, .thing.hash). |
| 73 | |
| 74 | * A cue alters and adds to your class as needed to implement the cue.[[br]] |
| 75 | For example the .enumerate cue when used on .NET will make your class implement |
| 76 | IEnumerable and IEnumerable<of> while adding a method for each, for a total of two new methods.[[br]] |
| 77 | This provides the capability of using your object in a for loop ("for a in mycollection, ...") |
| 78 | and pass it where enumerables are expected ("List<of T>(...)"). |
| 79 | |
| 80 | * Cues cannot necessarily be reflected on by name at run-time as their run-time names may be |
| 81 | different by platform (.NET "!GetHashCode" vs. JVM "hashCode"). |
| 82 | |
| 83 | |
| 84 | The intention is to provide implementations of the supported cues in a portable way between |
| 85 | platforms and in some cases (like .enumerate) in a more convenient manner. |
| 86 | |
| 87 | |
| 88 | == Initializer == |
| 89 | {{{ |
| 90 | cue init |
| 91 | }}} |
| 92 | |
| 93 | The init cue is used to denote an initializer for a class instance. |
| 94 | |
| 95 | The initializer code is implicitly invoked on object construction to set the contents of an object |
| 96 | instance to an initial state. |
| 97 | |
| 98 | It doesnt return any value and is not inherited: |
| 99 | i.e baseclass initialization must be done with an explicit call to a baseclass or sibling initializer |
| 100 | |
| 101 | Constructor chaining can be done to another constructor in the same class [[br]] |
| 102 | (usually to one with a different number or types of args) [[br]] |
| 103 | or to a superclass constructor (using '''base.init''') [[br]] |
| 104 | - this call must be the first executable line in the initializer code body. |
| 105 | |
| 106 | If an init cue is not specified the compiler runtime generates a (default) noArg constructor |
| 107 | that does nothing. |
| 108 | |
| 109 | |
| 110 | == Destructor == |
| 111 | {{{ |
| 112 | cue finalize |
| 113 | }}} |
| 114 | |
| 115 | Called implicitly on object destruction (at an indeterminate time).[[br]] |
| 116 | Nominally responsible for release of any additional stored resources [[br]] |
| 117 | e.g File handles, shared memory descriptors, sockets. |
| 118 | |
| 119 | But please see the various platform notes (.Net and JVM) on issues with use of [[br]] |
| 120 | destructors and finalizers and hints toward use of Disposal Interfaces instead (IDispose). |
| 121 | |
| 122 | |
| 123 | == Hash Code Calculation == |
| 124 | {{{ |
| 125 | cue hash as int |
| 126 | }}} |
| 127 | |
| 128 | Used to calculate a hash code (single unique id) for an object instance. |
| 129 | |
| 130 | The platform Framework calls this implicitly when needed [[br]] |
| 131 | (e.g. hash generation for Dictionary keys). |
| 132 | |
| 133 | The .hash cue is also an exception to the 'should not call a cue directly' note above.[[br]] |
| 134 | It is considered "externally visible" and can be invoked like an ordinary method. |
| 135 | |
| 136 | === Platform .NET === |
| 137 | see Object !GetHashCode |
| 138 | |
| 139 | == Comparison == |
| 140 | {{{ |
| 141 | cue compare(other) as int |
| 142 | }}} |
| 143 | |
| 144 | Provide a comparison calculation for the ordering of instances of a class, |
| 145 | this instance against the provided one. |
| 146 | |
| 147 | The return value is 0 for equality, negative for .this < other, positive for .this > other |
| 148 | |
| 149 | === Platform .NET === |
| 150 | see IComparable(<T>).!CompareTo Method |
| 151 | |
| 152 | == Object equality == |
| 153 | {{{ |
| 154 | cue equals(other) as int |
| 155 | }}} |
| 156 | |
| 157 | Method used to determine if this instance is equal to another object. [[br]] |
| 158 | Nominally called as a result of "a == b" expressions |
| 159 | |
| 160 | Can be pretty much boilerplate along the following lines |
| 161 | {{{ |
| 162 | cue equals(other [as Object]) as bool |
| 163 | if this is other, return true |
| 164 | if other inherits <!ThisClass> |
| 165 | return <boolean comparisons on equality of instance fields> |
| 166 | return false |
| 167 | }}} |
| 168 | |
| 169 | === Platform .NET === |
| 170 | see Object.equals method |
| 171 | |
| 172 | |
| 173 | == Provide enumeration/iteration capability == |
| 174 | {{{ |
| 175 | cue enumerate as <Type>* |
| 176 | }}} |
| 177 | |
| 178 | This cue provides an implementation of the Enumerable/Iterable pattern for containers |
| 179 | such that the class supports the idea of enumeration/iteration.[[br]] |
| 180 | i.e so that the cobra construct |
| 181 | {{{ |
| 182 | for item in <myCollectionObject> |
| 183 | }}} |
| 184 | works such that {{{item}}} gets each item stored in the object one at a time. |
| 185 | |
| 186 | It may (probably will) insert additional (boilerplate) code to provide exposure of this capability |
| 187 | in the framework approved manner (Enumerator/Iterator) |
| 188 | |
| 189 | === Platform .NET === |
| 190 | see IEnumerable and IEnumerable<of> |
| 191 | |
| 192 | |
| 193 | == Examples == |
| 194 | {{{ |
| 195 | class Customer |
| 196 | |
| 197 | cue init(name as String) |
| 198 | base.init |
| 199 | _name = name |
| 200 | |
| 201 | cue finalize |
| 202 | pass # release any held resources (file handles, sockets, ...) |
| 203 | |
| 204 | get name from var as String |
| 205 | |
| 206 | cue equals(other) as bool |
| 207 | if this is other, return true |
| 208 | if other inherits Customer |
| 209 | return .name == other.name |
| 210 | else |
| 211 | return false |
| 212 | |
| 213 | cue hash as int |
| 214 | return .name.hash |
| 215 | }}} |
| 216 | |
| 217 | == Notes == |
| 218 | |
| 219 | Currently only "cue init" is fully supported |
| 220 | |
| 221 | While you may specify access modifiers and return types in a cue the implementation may |
| 222 | modify, augment or ignore these to conform to the platform requirements or restrictions |