Classes & objects
Since beta-2.0.0 you can define your own types. A class groups fields (data) and methods (functions that work on that data). Inside a method, self is the object the method was called on.
ton.class Point {
ton.function init(x, y) {
self.x = x
self.y = y
}
ton.function distanceTo(other) {
return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
}
ton.function toString() {
return f"({self.x}, {self.y})"
}
}
ton.Point a = Point(0, 0)
ton.let b = Point(3, 4)
print(a.distanceTo(b)) // 5
print(b) // (3, 4) — print/str/f-strings use toString()
b.x = 10 // fields can be read and written with the dot
- Creating an object: call the class like a function. Its
initmethod (the constructor) receives the arguments; withoutinit, the class takes no arguments. - Field declarations in the class body (
ton.int count = 0,ton.let items = []) give every new object its own initial value, beforeinitruns. Fields can also be created at any time by assigningself.name = .... - Typed variables:
ton.Point p = ...checks that the value is aPoint(or a subclass of it), ornil. toString(), if defined, is used whenever the object is turned into text. Without it, an object prints asPoint{x: 3, y: 4};json(obj)gives{"x":3,"y":4}.- Methods are values:
ton.let f = point.toStringkeepsselfbound, sof()works later. - Objects are passed by reference (like arrays and dicts):
==is true only for the very same object.copy(obj)/deepcopy(obj)duplicate one.
Inheritance — extends makes a class reuse (and override) everything from a parent class; super.method(...) calls the parent's version:
ton.class Animal {
ton.string sound = "..."
ton.function init(name) { self.name = name }
ton.function speak() { return f"{self.name} says {self.sound}" }
}
ton.class Dog extends Animal {
ton.int tricks = 0
ton.function init(name) {
super.init(name)
self.sound = "woof"
}
ton.function learn() {
self.tricks++
return self // returning self allows chaining
}
}
ton.Dog rex = Dog("Rex")
print(rex.speak()) // Rex says woof
print(rex.learn().learn().tricks) // 2
print(isinstance(rex, Animal)) // true
print(type(rex)) // Dog
Objects work with the rest of the language: "x" in point tests a field, keys(obj)/values(obj)/items(obj) list fields, ton.let {x, y} = point destructures one, {...point} copies its fields into a dict, and throw MyError("...") throws one (the catch receives the object itself).