|
Каждая таблица и объект типа userdata могут иметь мета-таблицу — обычную таблицу, поля которой определяют поведение исходного объекта при применении к нему некоторых специальных операций. Например, когда объект оказывается операндом при сложении, интерпретатор ищет в мета-таблице поле с именем __add и, если такое поле присутствует, то использует его значение как функцию, выполняющую сложение. Мета-таблицы позволяют определить поведение объекта при арифметических операциях, сравнениях, конкатенации и индексировании. Также можно определить функцию, вызываемую при освобождении объекта типа userdata. Индексы (имена полей) в мета-таблице называются событиями, а соответствующие значения (обработчики событий) — метаметодами.
По умолчанию вновь созданная таблица не имеет мета-таблицы. Любую таблицу mt можно сделать мета-таблицей таблицы t, вызвав функцию setmetatable(t, mt). Функция getmetatable(t) возвращает мета-таблицу таблицы t или nil, если таблица не имеет мета-таблицы. Любая таблица может выполнять роль мета-таблицы для любой другой таблицы, в том числе и для себя.
Lua определяет следующие события:
__add, __sub, __mul, __div арифметические операции __pow возведение в степень __unm унарный минус __concat конкатенация __eq, __lt, __le операции сравнения __index доступ по отсутствующему индексу __newindex присвоение новому элементу таблицы __call вызов функции __tostring преобразование в строку __metatable получения мета-таблицы |
Выражение a ~= b вычисляется как not (a == b). Выражение a > b вычисляется как b < a. Выражение a >= b вычисляется как b <= a. При отсутствии метаметода __le операция <= вычисляется как not (b < a) т.е. с помощью метаметода __lt.
Для бинарных операций выбор обработчика производится следующим образом: опрашивается первый операнд и, если он не определяет обработчик, то опрашивается второй операнд. Для операций сравнения метаметод выбирается только если сравниваемые операнды имеют одинаковый тип и одинаковый метаметод для выполнения этой операции. В руководстве пользователя приведен псевдокод на Lua, демонстрирующий контекст вызова метаметодов.
Обработчик события __index может быть функцией или таблицей. В случае функции обработчик вызывается и ему передается таблица и значение индекса. Такая функция должна возвращать результат индексирования. В случае таблицы происходит повторное индексирование этой таблицы тем же индексом. Если присутствует обработчик события __newindex, то он вызывается вместо присвоения значения новому элементу таблицы. Если этот обработчик является таблицей, то присвоение производится в этой таблице.
Метаметод __tostring позволяет обработать преобразование объекта (таблицы или userdata) в строку. Метаметод __metatable позволяет обработать операцию получения мета-таблицы. Если у этого поля в мета-таблице установлено значение, то функция getmetatable() будет возвращать значение этого поля, а функция setmetatable() будет завершаться с ошибкой.
Функция rawget(tbl, idx) позволяет прочитать поле таблицы в обход механизма мета-методов. Аналогичный доступ на запись предоставляет функция rawset(tbl, idx, val). Функция rawequal(t1, t2) сравнивает объекты в обход механизма мета-методов.
Дата добавления: 2015-02-16; просмотров: 89 | Поможем написать вашу работу | Нарушение авторских прав |