Jump to content

[Lua] Магия с типами или debug.setmetatable


Recommended Posts

Приветствую всех, господа

В этой теме я расскажу о некоторых возможностях функции debug.setmetatable

Когда я только познакомился с Lua, первым делом у меня возник вопрос "а как получить символ из строки?", кто знаком с Си или с Pawn наверное знают, что это делается путём обращения к строке по индексу, в Lua такого нет, а обращаться через sub( 1, 1 ) не очень то и удобно, но благо разработчики оставили нам возможность "перебивания" мета-таблиц для определённого типа с помощью debug.setmetatable. И так, приступим:

Для начала нужно получить мета-таблицу у строки

local _string_mt = debug.getmetatable( "" ); 

И переопределить событие __index которое вызывается при чтении индекса из таблицы

function _string_mt:__index( index ) -- обратите внимание, что функция объявлена через двоеточие - это значит, что будет передаваться скрытый аргумент self который будет указывать на нашу строку  
    if type( index ) == 'number' then -- тут всё просто, если индекс числового типа,  
        return self:sub( index, index );  -- то возвращаем подстроку строки self 
    end  
    -- иначе всё необходимое для 
    return string[ index ];  -- для базовой работы методов len, sub, gsub и т.д. 
end 

И последний шаг, применяем мета-таблицу к строкам

debug.setmetatable( "", _string_mt ); 

Возможно многим нравится стиль конкатенации строк оператором + (плюс) как в JavaScript или в C++ (например в std::string), способ реализации выкладываю ниже

Для этого мы будет использовать событие __add которое вызывается при "сложении" чего либо с чем либо, поэтому когда вы попытаетесь "сложить строку", то будет вызван этот обработчик

function _string_mt:__add( str ) 
    return self .. str; 
end 

На самом деле я бы не рекомендовал использовать это, так как в случае возникновения ошибки, вы не сможете определить её место (тут вам поможет только pcall)

Таким же методом можно сделать и удаление из строки оператором - (минус)

Например ("hello from russia")-("from") вернёт нам "hello russia"

function _string_mt:__sub( str ) 
    return self:gsub( str, '' ); 
end 

А вот так мы добавим возможность вызывать методы для чисел

debug.setmetatable( 0, 
    {   
        __index = function( self, index )   
            return math[ index ];   
        end 
    } 
); 

Брать мета-таблицу у чисел мы не стали, так как стандартно её нет, но вообще желательно это проверить, мало ли что

Теперь мы можем делать так:

print( ( 12 ):random( 34 ) ); 

На этом пока всё. Статья была написана скорее для тех кто уже ознакомлен с понятием "мета-таблицы" в Lua, ибо на самом деле это далеко не весь их функционал, поэтому возможно имеет смысл написать урок на эту тему

Если есть вопросы - задавайте, постараюсь ответить

Копирование запрещено

Edited by Guest
  • Like 2
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...