Pyro

A dynamically-typed, garbage-collected scripting language.

Version 0.19.2

Classes


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";
    }
}

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,
};

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 return true if the receiver contains item, otherwise false.

:$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 the with 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 and set 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 an err 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 form receiver & 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 form receiver | 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 form receiver ^ 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 form receiver == other and other == receiver.

If both receiver and other 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 form receiver > 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 form receiver >= 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 form receiver >> 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 form receiver < 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 form receiver <= 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 form receiver << 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 form receiver - 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 form receiver 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 form receiver % 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 form receiver + 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 form receiver 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 form receiver / 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 form receiver // 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 form receiver * 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 form receiver ** 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 form other & 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 form other | 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 form other ^ 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 form other > 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 form other >= 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 form other >> 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 form other < 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 form other <= 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 form other << 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 form other - 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 form other 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 form other % 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 form other + 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 form other 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 form other / 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 form other // 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 form other * 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 form other ** 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.