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
self
orsuper
keywords.
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
Uninitialized fields have the default value null
.
You can specify a default value for a field in a class definition, e.g.
class Foo { pub var bar = 123; pub var baz; } var foo = Foo(); assert foo.bar == 123; assert foo.baz == null;
A default field value must be a simple literal — one of i64
, f64
, rune
, str
, bool
, or null
.
(This restriction only applies to instance fields. Static fields can be initialized to any value.)
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
in
operator. The method should returntrue
if 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. -
:$end_with()
-
This method will be called when a
with
block exits. The method will be called even if the code in thewith
block panics or returns early. Can be used to run clean-up code. -
:$fmt(format_specifier: str) -> str
-
This method should return a string representation of the instance formatted according to the
format_specifier
string. -
:$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
map
andset
types. -
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 anerr
if 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::json
library 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
err
if 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 == other
andother == receiver
.If both
receiver
andother
have:$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
mod
operator 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
rem
operator 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
mod
operator 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
rem
operator 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.