Sidebar

Home



Expressions V4


Tutorials

How-To

Reference

  Lexical basics
  Type system
  Variables and assignment
  Operators
  Expression rules
  Control flow
  Functions
  Built-in functions
   None and NaN
   Arithmetic
   Algebra
   Logarithmic and Exponential
   Trigonometric
   Rounding and Centering
   Strings
   Output, Formatting, Clipboard, and Errors
   Dialog Functions
   Platform and Paths
  Methods and properties
  Built-in methods
   Common Value Methods
   Number Methods
   String Basic Methods
   String Slice Methods
   String Parsing Methods
   String Formatting Methods
   String Regex Methods
   String Trim and Case Methods
  Objects
  Built-in objects
   Global objects
    settings
    controller
    session
    python
   Collections
    array
    map
    bytes
   File Format I/O
    image_data
    image_stream
   Utils
    crypto
    timer
   Comm
    serial
   Dialogs
    file_open
    file_save
    msg_ok
    msg_ok_cancel
    msg_yes_no
    msg_password
   GUI objects
    window
    panel
    group
    splitpanel
    label
    textbutton
    drawablebutton
    togglebutton
    togglegroup
    textinput
    textedit
    numinput
    slider
    combobox
    listbox
    progressbar
    led
    separator
    menu
    image
    snake
  Classes and user-defined objects
  Include system
  Error model
  Execution model and sessions
  Host integration
  Limits and performance
  Formal reference
  Glossary

Cookbook

exprv4:reference:classes_and_user_defined_objects

Classes and User-defined Objects

Classes define user-created object types. A class contains constructor code, fields, and methods.

User-defined objects behave like other Expr objects: they can be stored in variables, passed to functions, returned from functions, used as callback owners, and accessed with method/property syntax.


Class Definition

A class is declared with `class`, a name, a parameter list, and a body.

class ToolInfo(number, diameter)
{
    Number = number;
    Diameter = diameter;
 
    function Radius()
    {
        return Diameter / 2;
    }
}

The class name becomes a constructor in the current session.

tool = ToolInfo(3, 6.0);
print(tool.Number);      // 3
print(tool.Radius());    // 3

Class declarations are top-level declarations. They are not allowed inside `if`, `while`, `for`, or other statement blocks.


Constructor Body

The class body is also the constructor body.

When an object is created, Expr runs the non-function statements in the class body once for that new object.

class ProbeResult(x, y, z)
{
    X = x;
    Y = y;
    Z = z;
    HasError = false;
}
 
result = ProbeResult(10, 20, -1);

Assignments in the constructor create object fields.

Function declarations inside the class body do not run during construction. They define methods.


Constructor Parameters

Class constructor parameters are positional.

class Point(x, y)
{
    X = x;
    Y = y;
}
 
p = Point(10, 20);

The argument count must match the parameter count. Default arguments and keyword arguments are not supported.

Point(10);           // error
Point(10, 20, 30);   // error

Use empty parentheses when a class has no parameters:

class Counter()
{
    Value = 0;
}
 
c = Counter();

Fields

Fields are per-object values.

Inside a constructor or method, plain assignment can create or update a field:

class Counter(start)
{
    Value = start;
 
    function Inc()
    {
        Value = Value + 1;
        return Value;
    }
}

Fields can be read with property syntax:

c = Counter(5);
print(c.Value);      // 5

Inside a method, `this.field` explicitly reads a field from the current object:

class Counter(start)
{
    Value = start;
 
    function Read()
    {
        return this.Value;
    }
}

Direct property assignment is not supported:

c.Value = 10;        // error
this.Value = 10;     // error

To change a field from inside a constructor or method, assign the bare field name.


Local Variables and Fields

`set` creates a local variable. It does not create or update an object field.

class Counter(start)
{
    Value = start;
 
    function Test()
    {
        set Value = 100;
        return this.Value;      // still the object field
    }
}

Use `this.field` when a local variable or parameter has the same name as a field.

class ToolInfo(number)
{
    Number = number;
 
    function SetNumber(number)
    {
        Number = number;
        return this.Number;
    }
}

Compound assignment can update an object field when the target resolves to that field:

class Counter()
{
    Value = 0;
 
    function Inc()
    {
        Value += 1;
        return Value;
    }
}

Compound assignment through property syntax is not supported:

this.Value += 1;     // error

Methods

Methods are declared with `function` inside the class body.

class Accumulator()
{
    Total = 0;
 
    function Add(value)
    {
        Total += value;
        return Total;
    }
}
 
acc = Accumulator();
acc.Add(10);
acc.Add(5);

A method call uses the same syntax as built-in object method calls:

object.Method(arguments);

Methods can return any Expr value. Returning `this` is useful for chaining:

class Builder()
{
    Text = '';
 
    function Add(text)
    {
        Text += text;
        return this;
    }
 
    function Get()
    {
        return Text;
    }
}
 
s = Builder().Add('A').Add('B').Get();

Method overloading by argument count is not supported for user-defined class methods. Use different method names.


this

`this` is available inside class constructor code and class methods.

Use `this` to:

  • read fields explicitly
  • call another method on the same object
  • return the current object
  • create a method reference for callbacks
class Counter(start)
{
    Value = start;
 
    function Add(value)
    {
        Value += value;
        return this.Value;
    }
 
    function AddTwice(value)
    {
        return this.Add(value) + this.Add(value);
    }
}

Inside a method, a bare function-style call can resolve to a method on `this` before falling back to session functions and built-in functions.

class Counter(start)
{
    Value = start;
 
    function Add(value)
    {
        Value += value;
        return Value;
    }
 
    function AddTwice(value)
    {
        return Add(value) + Add(value);
    }
}

Use `this.Add(value)` when you want the method call to be explicit.


Method References and Callbacks

A method can be referenced without calling it.

class DialogScript()
{
    Count = 0;
 
    function OnClick()
    {
        Count += 1;
    }
 
    function Show()
    {
        btn = textbutton().text('Run').on_click(this.OnClick);
        window().title('Demo').size(200, 100).add(btn).show();
    }
}
 
script = DialogScript();
script.Show();

`this.OnClick` is a method reference. It can be passed to APIs that expect a callback.

A method reference is an object value. It can also be called explicitly with `call(…)`.

callback = script.OnClick;
callback.call();

Callback argument rules depend on the object or host API that invokes the callback.


Namespaced Classes

Class names can use namespaces.

class Math::Accumulator()
{
    Total = 0;
 
    function Add(value)
    {
        Total += value;
        return Total;
    }
}
 
acc = Math::Accumulator();
acc.Add(5);

Namespaced includes can also place included class definitions into a namespace. See Include system.


Class and Function Name Resolution

When a call name can refer to both a class constructor and a function, Expr resolves the class constructor first.

function Box()
{
    return 'function';
}
 
class Box()
{
    Value = 'class';
}
 
b = Box();           // creates a Box object

Re-defining a class name in the same session replaces the previous class definition.


Sessions

User-defined classes belong to the active Expr session.

A class defined in one named session is not visible in another named session unless it is defined there too.

class Box(value)
{
    Value = value;
}
 
b = Box(7);

Use the global `session` object to inspect current session classes:

print(session.list_classes());

See session and Execution model and sessions.


Object Assignment and Clone

Object variables hold object references.

class Person()
{
    Name = '';
 
    function SetName(name)
    {
        Name = name;
    }
}
 
p1 = Person();
p1.SetName('A');
 
p2 = p1;
p2.SetName('B');
 
print(p1.Name);      // B

Use `clone()` when you need an independent copy.

p3 = p1.clone();
p3.SetName('C');

User-defined objects are cloneable when their field values are cloneable. If the object graph contains a non-cloneable object, `clone()` raises an error.


Current Limitations

Expr classes currently do not support:

  • inheritance
  • interfaces
  • static members
  • overloaded constructors
  • overloaded methods by argument count
  • direct property assignment such as `obj.field = value`
  • class declarations inside statement blocks

Previous: snake

Next: Include system

exprv4/reference/classes_and_user_defined_objects.txt · Last modified: by 127.0.0.1

Page Tools