Version: v0.7.0 - Beta.  We welcome contributors & feedback.

Classes & Objects

Overview 

THT supports object-oriented programming (OOP), with some differences from PHP.

For example, it emphasizes object composition and flexible Traits, over single inheritance.

The overall philosophy is to make common OOP patterns and best practices more convenient, while discouraging patterns that often lead to less maintainable code.

The Basics 

An object is like a bundle of data that is attached to a group of functions that work on that data.

For example, you are already familiar with built-in object types like Strings and Lists, which have methods likes split and reverse.

Classes

You can create your own object types by defining a class, which is just a template for creating objects.

Classes are always defined in a module of the same name.

They are loaded the same way as modules — via the load command.

// File: modules/forum/ForumPost.tht
//----------------------------------

class ForumPost {
    ...
}

// Another file
//----------------------------------

load('forum/ForumPost')

Fields

Object data is defined with the fields keyword, followed by a Map.

class Character {

    fields {
        name: 'Theralt',
        health: 33,
        weapon: 'sword',
    }
}

Creating the Object

To create (or “instantiate”) an object from a class, simply call it like a function (with parens).

To access its members, use the dot (.) operator.

// Create a new character object
$char = Character()

$char.name
//= 'Theralt'

Methods

A method is just a function that is defined inside of a class.

Methods can access other members (fields & methods) of the current object by using the @ (“this”) symbol, which is just a shorter version of the $this variable in PHP and other languages.

class Character {

    fields {
        name: 'Thatia',
    }

    fn sayHello {
        print('Greetings, I am ' ~ @.name)
        //                         ^^^^^^
    }
}

// Another file
//----------------------------------

$char = Character()

$char.sayHello()
//= 'Greetings, I am Thatia'

Public Fields 

Technically, the above examples will give you an error because all class members are private by default — meaning they are only accessible inside the class.

To make fields accessible outside the class, add the public keyword.

class Character {

    public fields {
        name: 'Thanolt',
    }

    // private by default
    fields {
        weapon: 'sword'
    }
}

// Another file
//----------------------------------

$char = Character()

print($char.name)
//= 'Thanolt'

print($char.weapon)
// ✕ ERROR - 'weapon' is a private field

Public Methods

Likewise, add public to a method to make it callable from the outside.

class Character {

    public fn walk {
        print('Walking...')
        @.updatePosition()
    }

    // private by default
    fn updatePosition {
        ...
    }
}

// Another file
//----------------------------------

$char = Character()

$char.walk()
//= 'Walking...'

$char.updatePosition()
// ✕ ERROR - private method

Read-Only Fields

Unlike other languages, in THT, public fields are read-only outside of the class.

This helps maintain a clear boundary for objects, as discussed in “Setters” below.

class Character {
    public fields {
        name: 'Thanolt',
    }
}

// Another file
//----------------------------------

$char = Character()

print($char.name)
//= 'Thanolt'

$char.name = 'Timmy'
// ✕ ERROR - public fields are read-only

Meta-Methods 

Every object has a number of built-in meta-methods, for dynamically accessing fields, etc.

See Object for all methods.

Hook Methods

You can also define “hook” methods that are triggered by certain events.

See Object Hooks for all methods.