2.15. Metamethods

Metamethods are a mechanism that allows the customization of certain aspects of the language semantics. Those methods are normal functions placed in a table parent(delegate) or class declaration; Is possible to change many aspect of a table/class instance behavior by just defining a metamethod. Class objects(not instances) supports only 2 metamethods _newmember, _inherited .

For example when we use relational operators other than ‘==’ on 2 tables, the VM will check if the table has a method in his parent called ‘_cmp’ if so it will call it to determine the relation between the tables.:

local comparable={
    _cmp = function (other)
    {
        if(name<other.name)return -1;
        if(name>other.name)return 1;
        return 0;
    }
}

local a={ name="Alberto" }.setdelegate(comparable);
local b={ name="Wouter" }.setdelegate(comparable);

if(a>b)
    print("a>b")
else
    print("b<=a");

for classes the previous code become:

class Comparable {
    constructor(n)
    {
        name = n;
    }
    function _cmp(other)
    {
        if(name<other.name) return -1;
        if(name>other.name) return 1;
        return 0;
    }
    name = null;
}

local a = Comparable("Alberto");
local b = Comparable("Wouter");

if(a>b)
    print("a>b")
else
    print("b<=a");

2.15.1. _set

_set(idx,val)

invoked when the index idx is not present in the object or in its delegate chain. _set must ‘throw null’ to notify that a key wasn’t found but the there were not runtime errors(clean failure). This allows the program to defferentieate between a runtime error and a ‘index not found’.

2.15.2. _get

_get(idx,val)

invoked when the index idx is not present in the object or in its delegate chain. _get must ‘throw null’ to notify that a key wasn’t found but the there were not runtime errors(clean failure). This allows the program to defferentieate between a runtime error and a ‘index not found’.

2.15.3. _newslot

_newslot(key,value)

invoked when a script tries to add a new slot in a table.

if the slot already exists in the target table the method will not be invoked also if the “new slot” operator is used.

2.15.4. _delslot

_delslot(key)

invoked when a script deletes a slot from a table. if the method is invoked squirrel will not try to delete the slot himself

2.15.5. _add

_add(other)

the + operator

returns this + other

2.15.6. _sub

_sub(other)

the - operator (like _add)

2.15.7. _mul

_mul(other)

the * operator (like _add)

2.15.8. _div

_div(other)

the / operator (like _add)

2.15.9. _modulo

_modulo(other)

the % operator (like _add)

2.15.10. _unm

_unm()

the unary minus operator

2.15.11. _tyoeof

_tyoeof()

invoked by the typeof operator on tables ,userdata and class instances

returns the type of this as string

2.15.12. _cmp

_cmp(other)

invoked to emulate the < > <= >= and <=> operators

returns an integer as follow:

returns relationship
> 0 if this > other
0 if this == other
< 0 if this < other

2.15.13. _call

_call(other)

invoked when a table, userdata or class instance is called

2.15.14. _cloned

_cloned(original)

invoked when a table or class instance is cloned(in the cloned table)

2.15.15. _nexti

_nexti(previdx)

invoked when a userdata or class instance is iterated by a foreach loop

if previdx==null it means that it is the first iteration. The function has to return the index of the ‘next’ value.

2.15.16. _tostring

_tostring(previdx)

invoked when during string conacatenation or when the print function prints a table, instance or userdata. The method is also invoked by the sq_tostring() api

must return a string representation of the object.

2.15.17. _inherited

_inherited(attributes)

invoked when a class object inherits from the class implementing _inherited the this contains the new class.

return value is ignored.

2.15.18. _newmember

_newmember(index,value,attributes,isstatic)

invoked for each member declared in a class body(at declaration time).

if the function is implemented, members will not be added to the class.