Metamethods

Squirrel 3.0

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

_set

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'.

function _set(idx,val) //returns val

_get

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'.

function _get(idx) //return the fetched values

_newslot

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

function _newslot(key,value) //returns val

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

_delslot

invoked when a script deletes a slot from a table.

if the method is invoked squirrel will not try to delete the slot himself

function _delslot(key)

_add

the + operator

function _add(op) //returns this+op

_sub

the – operator (like _add)

_mul

the * operator (like _add)

_div

the / operator (like _add)

_modulo

the % operator (like _add)

_unm

the unary minus operator

function _unm()

_typeof

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

function _typeof() //returns the type of this as string

_cmp

invoked to emulate the < > <= >= operators

function _cmp(other)

returns an integer:

>0 if this > other
0 if this == other
<0 if this < other

_call

invoked when a table, userdata or class instance is called

function _call(original_this,params…)

_cloned

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

function _cloned(original)

_nexti

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

function _nexti(previdx)

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

_tostring

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

function _tostring()

must return a string representation of the object.

_inherited

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

function _inherited(attributes)

return value is ignored.

_newmember

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

function _newmember(index,value,attributes,isstatic)

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