Methods - brombres/Rogue GitHub Wiki
Class definitions can have sections defining both METHODS and GLOBAL METHODS.
class XYZ
PROPERTIES
property_name : Type
METHODS
method init
# Initializer; automatically called for constructor XYZ()
method init( param:Type )
# Overloaded initializer; automatically called for constructor XYZ(arg)
method init_object
# Automatically called whenever an object is created, before init().
# The compiler inserts code here to initialize properties.
method name( param1:Type1, param2=default_value:Type2, property_name )
method name( ... ) [attribute list]
method name( ... )->ReturnType
...
return result
method name( ..., &default_flag, &default_param:Type, ... )
...
if (...) return
method name( ... )->this
...
return this
method call
# Functor syntax allows objects to be invoked using a function call syntax.
# Writing obj() is shorthand for obj.call().
method call( value:Real64 )->Int32
# Functor calls can be overloaded. This method can be called with e.g. "println obj(x)"
# and it will translate into "println obj.call(x)".
method name<<$A,$B>>( arg:$A )->$B
# Method template. Call with e.g. 'name<<Real64,Int32>>(value)'. Template specializers
# (<<...>>) can be omitted if the placeholder count (e.g. <<$A,$B>> is 2) matches the
# number of args; then the arg types will be used as the specializer types.
method name<<String,Int32>>( arg:String )->Int32
# Method template "overload" that will be used for calls to 'name<<String,Int32>>'
# instead of the default template definition.
method to->Type
# Conversion method. Called for e.g. 'obj->Type' or 'this->Type'.
return this_converted_to_type
method to->Type(param1:Type1,...)
# Conversion method with args. E.g. 'obj->Type(arg1,arg2)'.
If a parameter doesn't give a :Type and it's not a &default_parameter (Named Argument) then it is an auto-store parameter. A property of the same name must exist and the parameter value is automatically stored in the property at the beginning of the method.
For example, this pattern is common in object-oriented languages:
method init( x:Int32, y:Int32 )
this.x = x
this.y = y
An auto-store parameter eliminates the boilerplate and has the same effect as the code above:
method init( x, y )
obj.m_name
obj.m_name()
obj.m_name(...)
obj.m_name( arg1, arg2, ... )
obj.m_name( ..., &named_arg, &!named_arg, &named_arg2=value, &=named_arg_3 )
local result = obj.m_name(...)
See also: Named Arguments.
A method (AKA Object Method) can access any properties or other methods contained within the context of the object the method was called on.
Object methods all have an implicit variable this which is a reference to the object context that the method was called on.
If this is used as a return type, it sets the return type to be the type of "this" class and implies that "this" object (as opposed to a different object) will be the return value, although that is not enforced in the compiler. This is most often used for call chaining, but see Context Blocks as a better alternative to call chaining in most cases.
class XYZ
GLOBAL METHODS
method name( arg1:Type1, arg2=default_value:Type2, property_name )
method name( ... ) [attribute list]
method name( ... )->ReturnType
method name( ..., &named_arg, &named_arg2:Type, ... )
...
return
return result
XYZ.m_name
XYZ.m_name()
XYZ.m_name( arg1, arg2, ... )
XYZ.m_name( ..., &named_arg, &!named_arg, &named_arg2=value, &=named_arg_3 )
local result = XYZ.m_name(...)
See also: Named Arguments.
Global methods (AKA class methods or static methods) are called at the class level instead of the object level like regular object methods. They are called on a class name rather than an object reference.
| Attribute | Description |
|---|---|
| abstract | Methods only (not global methods or routines). Declares an undefined method that can be called on a reference of the current class type but must be defined in an extended class. Classes declaring an [abstract] method must themselves be declared [abstract] and cannot be instantiated - only non-abstract extended classes can be instantiated. |
| api | Has the same effect as [essential] as a method attribute (but has differences as a class attribute). |
| append | Aspect methods only. When an aspect is incorporated into a class, the [append] attribute causes an aspect method to be merged in at the end of the class's definition of the same method. |
| critical criticalOverride |
A method overriding a [critical] method must make a prior call to the critical method or else include the [criticalOverride] attribute. In addition, a critical method override automatically becomes a [critical] method itself. |
| essential | An [essential] method will be kept in the transpiled C output even if it is unused. Note that [essential] object methods will not be kept if the class itself is unused; mark the class [essential] or [api] to prevent that. |
| fallback | If this method (e.g. x() or set_x(...)) is a getter or setter for a property of the same name (x), the property will be accessed directly when possible without going through the access method. This can be useful for method-only aspect classes which are incorporated into regular classes that define a property with the same name. |
| insert | Aspect methods only. When an aspect is incorporated into a class, the [insert] attribute causes an aspect method to be merged in at the beginning of the class's definition of the same method. |
| mutating | Compound methods marked [mutating] can change compound properties. The tradeoff is that mutating calls must be made directly on existing properties and local variables and cannot be made on the intermediate result of a call or expression. |
| novel | An opt-in safety attribute that ensures the current method is not overriding a prior (base class) method with the same signature. See also [override]. |
| override | An opt-in safety attribute that ensures the current method overrides a prior (base class) method with the same signature. See also [novel]. |
| preferred | A [preferred] method will be chosen among otherwise ambiguous methods when resolving a call. |
| propagated | Propagated methods are not inherited but are rather re-applied in each extended class as if they had been overridden with the same definition. This is useful when calls rely on the type of this object, as with a double dispatch mechanism. |