= Methods = Methods are blocks of code specific to a class. They can be thought of as providing the actions that a class instance can be told to do. Methods can take zero or a number of parameters passed to them and may return a value. Methods within a class are defined using the keyword '''def'''. If not explicitly specified, the returnType of a method is void (i.e nothing returned) and the [wiki:AccessModifiers access modifiers] are '''public, virtual'''. Like variables, if the name is prefixed with an '''_''' its access modifier defaults to ''protected'' and it is directly accessable from within the class method code.[[BR]] If the name is prefixed with '''!__''' its access modifier defaults to ''private''. Without either of those prefixes on the name of the method, the accessType is ''public, virtual'' and it must be accessed from within method code by prefixing the name with either '''this.''' or just '''.''' (dot) .[[BR]] == Method Grammar == {{{ def [as ] [is ] [has ] [] def () [as ] [is ] [has ] [] }}} === Method !ParamList === A parameter list is a comma separated list of name (and optionally type and parameter description modifier) specifications {{{ [as [] ] [, ...] }}} is optional and may be '''vari''' and/or a parameter direction indicator '''out''' or '''inout''' ( default if unspecified is '''in''')[[BR]] '''vari''' indicates the parameter name is a placeholder for a variable length arglist. Within the method this may be unpacked/accessed as a list.[[BR]] '''in''' (implicit) args are only passed into the method. Any changes made to the argument inside the method are not visible outside the method (pass-by-value)[[BR]] '''out''' the arg is returned from the method [[BR]] '''inout''' argument is both passed into the method and (any possibly changed) value is also returned from the method (pass-by-reference)[[BR]] If is unspecified it is defaulted to and treated as dynamic.[[BR]] == Example == {{{ #!cobra def meth( a, b is String, c is out String) c = b + "_meth" def sum(a as vari int) as int sum = 0 for i in a sum += i return sum }}} meth takes 3 args , the first and second are inward only and are typed as dynamic and a string respectively, [[br]] the third is only returned from the method as a string. sum takes a variable number of integer args and returns an integer. == Special Methods == These are named methods on a class that have some special responsibility or relationship to the Object Model[[BR]] (they were originally implemented as methods with special names but have since been redone specified as [wiki:Cue cues] They include: * Initializer '''init''' The __initializer__ (or constructor) method of a class is a special method named '''init''' which is implicitly called when a class instance is constructed. It's responsible for setting the contents of a class instance to an initial state. It doesnt return any value and is not inherited (i.e baseclass initialization must be done with an explicit call to a baseclass constructor). If an init method is not specified the compiler runtime generates a noArg constructor that does nothing (changed - this was original behaviour, now an init method must be explicitly provided). Constructor chaining can be done to another constructor in the same class (usually with a different number or Type of args) or to a Superclass constructor (using '''base.init''') - this call must be the first executable line in the init method. * Destructor '''finalize''' * !HashCode calculation '''hash''' hash as int * Comparison '''compare''' compare(other) as int * Equality '''equals''' equals(other) as int * Enumerator '''enumerate''' enumerate as T* == Method Body == A method body is the code that implements the methods actions or behaviour.[[BR]] In addition to the body, a methods contents may also include optional contracts specifications (pre method entry prerequisite conditions and post method exit postconditions )and optional Test clauses. Contract prerequisites are tagged with the keyword suffix '''require'''. [[BR]] Postconditions are suffixed with keyword '''ensure'''.[[BR]] Both of these may be a single expression (on the same line as keyword) or an indented clause on line following the keyword.[[BR]] Tests are always in an indented clause following the '''test''' suffix keyword. Inherited methods may augment contracts provided on ancestor methods.[[BR]] Prerequisites may be relaxed, postconditions can only be increased (??). [[BR]] Such augmentation is noted by an extra leading suffix :[[BR]] giving '''or require''' for preconditions, '''and ensure''' for postconditions[[BR]] otherwise contracts on submethods replace any contracts on ancestor methods. If tests or contracts are specified and any of these are indented clauses (i.e if any tests are given (always in an indented clause) or single or multiple prerequisite or postcondition expressions are given (in an indented clause) then the method body ''must'' also be tagged with the keyword suffix '''body''' and the method body code placed in a following indented clause. Examples {{{ #!cobra def simpleBump(i as int) as int require i >0 # prerequisite contract - single expression .counter += 1 # method body starts here - not indented .val += i return .val def simpleBump(i as int) as int require i >0 # prerequisite contract - single expression ensure .val > old .val # postcondition contract - single expression .counter += 1 # method body - not additionally indented .val += i return .val def simpleBump(i as int) as int test # unit test clause a = Inst() assert a.counter == 0 assert a.val == 0 a.simpleBump(1) assert a.counter ==1 assert a.val == 1 body ##method body - tagged and additionally indented .counter += 1 .val += i return .val def simpleBump(i as int) as int require # prerequisite contract - in indented clause (1 or many expressions) i >0 body # method body must be tagged and indented .counter += 1 .val += i return .val # this emits a syntax error - method body must be tagged and indented def simpleBump(i as int) as int require # prerequisite contract - in indented clause (1 or many expressions) i >0 .counter += 1 #method body - not additionally indented .val += i return .val }}}