Classes
- Class Definitions
- Fields and Methods
- Bound Methods
- Public/Private Members
- The Self Keyword
- Static Members
- Field Initializers
- Inheritance
- Object Literals
- Indexing
- Dollar Methods
Class Definitions
Class definitions look like this:
class Person { pub var name; pub var role = "programmer"; def $init(name) { self.name = name; } pub def info() { echo "${self.name} is a ${self.role}."; } }
Create an instance of a class by calling its name:
var dave = Person("Dave");
Arguments are passed to the optional $init() method.
Fields and Methods
Get or set an instance's fields using the field access operator ., e.g.
dave.role = "pyro programmer";
Call a method on an instance using the method access operator :, e.g.
dave:info();
Bound Methods
Methods are bound to their instances and you can pass them around just like any other value, e.g.
class Object { var value = 0; pub def get() { return self.value; } pub def set(arg) { self.value = arg; } } var object = Object(); var setter = object:set; var getter = object:get; setter(123); assert getter() == 123;
Public/Private Members
Fields and methods are private by default — use the pub keyword to make them public, e.g.
class Foo { pub var public_field; var private_field; pub def public_method() { return "public"; } def private_method() { return "private"; } }
- Public members can be accessed from inside or outside the class.
-
Private members can only be accessed from inside the class using the
selforsuperkeywords.
The Self Keyword
Use the self keyword inside a class to access the instance's fields and methods, e.g.
class Foo { var field; def private_method() { return self.field; } pub def public_method() { return self:private_method(); } }
Static Members
Static fields and methods are defined on the class object itself:
class Object { static var count = 0; static def increment() { Object.count += 1; } } Object:increment(); assert Object.count == 1;
Static members can't be accessed from instances of the class:
var obj = Object(); assert $is_err(try obj.count); assert $is_err(try obj:increment());
All static members are public.
Note that you can't use the self or super keywords inside static methods.
Field Initializers
You can specify a default value for each field in a class definition.
(Uninitialized fields have the default value null.)
class Object { pub var foo = 123 + 456; pub var bar; } var obj = Object(); assert obj.foo == 579; assert obj.bar == null;
- Default-value expressions for static fields are evaluated when the class definition itself is evaluated.
-
Default-value expressions for public and private fields are evaluated each time a new instance is created, before the
$init()method runs. They can capture local and global variables from the surrounding scope.
Inheritance
A class can inherit from a superclass using the extends keyword, e.g.
class Shape { var color; def $init(color) { self.color = color; } pub def info() { $println("color: {}", self.color); } } class Circle extends Shape { var radius; def $init(color, radius) { super:$init(color); self.radius = radius; } pub def info() { super:info(); $println("radius: {}", self.radius); } }
Subclass methods override superclass methods as you'd expect.
A subclass can use the super keyword to access an overridden superclass method.
Object Literals
You can create an instance of a class using object-literal syntax, e.g.
class Object { pub var foo; pub var bar; } var obj = Object as { foo: 123, bar: 456, };
- You can only set public field values in an object literal.
- Uninitialized fields retain their default value.
-
If the class has a zero-argument
$init()method, it will be called automatically before the object literal values are applied. -
You can't use an object literal for a class with a non-zero-argument
$init()method.
Indexing
You can add indexing support to a class by implementing $get(key) and/or $set(key, value) methods.
Accessing an index, e.g.
var foo = object[key];
is equivalent to calling the instance's $get(key) method.
Assigning to an index, e.g.
object[key] = value;
is equivalent to calling the instance's $set(key, value) method.
Dollar Methods
You can implement the $-prefixed methods listed below to overload operators or to add support for various language features to user-defined types:
-
:$call(arg1: any, arg2: any, ...) -> any -
Implementing this method makes instances of the type callable. When an instance is called, the call will be handled by this method.
-
:$contains(item: any) -> bool -
Implementing this method adds support for the
inoperator. The method should returntrueif the receiver containsitem, otherwisefalse. -
:$debug() -> str -
This method should return a string representation of the instance suitable for debugging.
The output of this method is used by the
$debug()function. -
:$enter() -
This method will be called when the instance enters a
withblock. -
:$exit() -
This method will be called when the instance exits a
withblock. The method will be called even if the code in thewithblock panics or returns early.This method can be used to run clean-up code for the instance.
-
:$fmt(format_specifier: str) -> str -
This method should return a string representation of the instance formatted according to the
format_specifierstring. -
:$get(key: any) -> any -
Implementing this method adds support for index-style read access to instances, e.g.
var value = instance[key];
Implementing a
:$set(key, value)method adds support for index-style write access to instances. -
:$hash() -> i64 -
Implementing this method returns a custom hash value for an instance.
- By default an instance's hash value is simply its memory address.
-
Hash values are used for looking up entries in the builtin
mapandsettypes. -
The output of this method is used by the
$hash()function. -
Instances that compare as equal using
==should have the same hash value.
-
:$init(arg1: any, arg2: any, ...) -
Constructor method for initializing new instances.
-
:$iter() -> iterator -
Implementing this method makes the type iterable.
The method should return an iterator — i.e. an object with a
:$next()method that returns either the next item from a sequence or anerrif the sequence has been exhausted.See the documentation on iterators for details.
-
:$json() -> str -
If implemented, this method should return a string containing the object serialized to JSON.
This method is used by the
std::jsonlibrary to serialize objects to JSON. -
:$next() -> any -
Implementing this method makes the type an iterator.
The method should return either the next item from a sequence or an
errif the sequence has been exhausted.See the documentation on iterators for details.
-
:$op_binary_amp(other: any) -> any -
Implementing this method overloads the binary
&operator for expressions of the formreceiver & other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_bar(other: any) -> any -
Implementing this method overloads the binary
|operator for expressions of the formreceiver | other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_caret(other: any) -> any -
Implementing this method overloads the binary
^operator for expressions of the formreceiver ^ other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_equals_equals(other: any) -> bool -
Implementing this method overloads the binary
==operator for expressions of the formreceiver == otherandother == receiver.If both
receiverandotherhave:$op_binary_equals_equals()methods, the method for the value on the left of the expression will be used.The
!=operator automatically returns the logical inverse of==and cannot be separately overloaded.If you overload this operator and you want to use your overloaded type as a key in hash maps or as a member in sets you should also overload the
:$hash()method to ensure that instances that compare as equal also have the same hash value. -
:$op_binary_greater(other: any) -> bool -
Implementing this method overloads the binary
>operator for expressions of the formreceiver > other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_greater_equals(other: any) -> bool -
Implementing this method overloads the binary
>=operator for expressions of the formreceiver >= other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_greater_greater(other: any) -> bool -
Implementing this method overloads the binary
>>operator for expressions of the formreceiver >> other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_less(other: any) -> bool -
Implementing this method overloads the binary
<operator for expressions of the formreceiver < other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_less_equals(other: any) -> bool -
Implementing this method overloads the binary
<=operator for expressions of the formreceiver <= other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_less_less(other: any) -> bool -
Implementing this method overloads the binary
<<operator for expressions of the formreceiver << other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_minus(other: any) -> any -
Implementing this method overloads the binary
-operator for expressions of the formreceiver - other— i.e. for cases when the receiver instance is on the left of the expression.Overloading the
-operator automatically overloads the-=operator. -
:$op_binary_mod(other: any) -> any -
Implementing this method overloads the binary
modoperator for expressions of the formreceiver mod other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_percent(other: any) -> any -
Implementing this method overloads the binary
%operator for expressions of the formreceiver % other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_plus(other: any) -> any -
Implementing this method overloads the binary
+operator for expressions of the formreceiver + other— i.e. for cases when the receiver instance is on the left of the expression.Overloading the
+operator automatically overloads the+=operator. -
:$op_binary_rem(other: any) -> any -
Implementing this method overloads the binary
remoperator for expressions of the formreceiver rem other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_slash(other: any) -> any -
Implementing this method overloads the binary
/operator for expressions of the formreceiver / other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_slash_slash(other: any) -> any -
Implementing this method overloads the binary
//operator for expressions of the formreceiver // other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_star(other: any) -> any -
Implementing this method overloads the binary
*operator for expressions of the formreceiver * other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_binary_star_star(other: any) -> any -
Implementing this method overloads the binary
**operator for expressions of the formreceiver ** other— i.e. for cases when the receiver instance is on the left of the expression. -
:$op_unary_minus() -> any -
Implementing this method overloads the unary
-operator for expressions of the form-receiver. -
:$op_unary_plus() -> any -
Implementing this method overloads the unary
+operator for expressions of the form+receiver. -
:$op_unary_tilde() -> any -
Implementing this method overloads the unary
~operator for expressions of the form~receiver. -
:$rop_binary_amp(other: any) -> any -
Implementing this method overloads the binary
&operator for expressions of the formother & receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_amp()method. -
:$rop_binary_bar(other: any) -> any -
Implementing this method overloads the binary
|operator for expressions of the formother | receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_bar()method. -
:$rop_binary_caret(other: any) -> any -
Implementing this method overloads the binary
^operator for expressions of the formother ^ receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_caret()method. -
:$rop_binary_greater(other: any) -> bool -
Implementing this method overloads the binary
>operator for expressions of the formother > receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_greater()method. -
:$rop_binary_greater_equals(other: any) -> bool -
Implementing this method overloads the binary
>=operator for expressions of the formother >= receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_greater_equals()method. -
:$rop_binary_greater_greater(other: any) -> any -
Implementing this method overloads the binary
>>operator for expressions of the formother >> receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_greater_greater()method. -
:$rop_binary_less(other: any) -> bool -
Implementing this method overloads the binary
<operator for expressions of the formother < receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_less()method. -
:$rop_binary_less_equals(other: any) -> bool -
Implementing this method overloads the binary
<=operator for expressions of the formother <= receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_less_equals()method. -
:$rop_binary_less_less(other: any) -> any -
Implementing this method overloads the binary
<<operator for expressions of the formother << receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_less_less()method. -
:$rop_binary_minus(other: any) -> any -
Implementing this method overloads the binary
-operator for expressions of the formother - receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_minus()method.Overloading the
-operator automatically overloads the-=operator. -
:$rop_binary_mod(other: any) -> any -
Implementing this method overloads the binary
modoperator for expressions of the formother mod receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_mod()method. -
:$rop_binary_percent(other: any) -> any -
Implementing this method overloads the binary
%operator for expressions of the formother % receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_percent()method. -
:$rop_binary_plus(other: any) -> any -
Implementing this method overloads the binary
+operator for expressions of the formother + receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_plus()method.Overloading the
+operator automatically overloads the+=operator. -
:$rop_binary_rem(other: any) -> any -
Implementing this method overloads the binary
remoperator for expressions of the formother rem receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_rem()method. -
:$rop_binary_slash(other: any) -> any -
Implementing this method overloads the binary
/operator for expressions of the formother / receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_slash()method. -
:$rop_binary_slash_slash(other: any) -> any -
Implementing this method overloads the binary
//operator for expressions of the formother // receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_slash_slash()method. -
:$rop_binary_star(other: any) -> any -
Implementing this method overloads the binary
*operator for expressions of the formother * receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_star()method. -
:$rop_binary_star_star(other: any) -> any -
Implementing this method overloads the binary
**operator for expressions of the formother ** receiver— i.e. for cases when the receiver instance is on the right of the expression.This method will only be called if the value on the left does not have an
:$op_binary_star_star()method. -
:$set(key: any, value: any) -
Implementing this method adds support for index-style write access to instances, e.g.
instance[key] = value;
Implementing a
:$get(key)method adds support for index-style read access to instances. -
:$str() -> str -
If implemented, this method returns the instance's default string representation.
The output of this method is used by the
$str()function.