Lua override # для строк
Я пытаюсь реализовать свой собственный метод длины для строк в Lua. Я успешно переопределил метод len() для строки, но я не знаю, как это сделать для оператора #.
orig_len = string.len
function my_len(s)
print(s)
return orig_len(s)
end
string.len = my_len
abc = 'abc'
Если я позвоню:
print(abc:len())
Это выводит:
abc
3
Но
print(#abc)
Выводит только "3", а это значит, что она называется функцией исходной длины вместо моей. Есть ли способ заставить # вызвать мою функцию длины?
2 ответа
Я пытаюсь реализовать свой собственный метод длины для строк в Lua.
Вы не можете сделать это от Луа.
Вам нужно изменить исходный код Lua, в частности виртуальную машину (lvm.c) и изменить обработку кода операции. OP_LEN
, В Lua 5.2 вам нужно изменить luaV_objlen
чтобы проверить метаметод перед получением фактической длины строки:
case LUA_TSTRING: {
tm = luaT_gettmbyobj(L, rb, TM_LEN); // <--- add this line
if (!ttisnil(tm)) // <--- add this line
break; // <--- add this line
setnvalue(ra, cast_num(tsvalue(rb)->len));
return;
}
Но это похоже на злоупотребление перегрузкой оператора, как перегрузка +
означать разделение или что-то.
Вы не можете переопределить #
оператор для строк в Lua, даже с метатаблицами: __len
Метаметод не применяется к строкам.
На самом деле, в Lua нет понятия переопределения операторов. Метаметоды Lua - это запасные варианты: они используются, когда Lua не может действовать самостоятельно. Таким образом, арифметические метаметоды не применяются к числам, а метаметод длины не применяется к строкам.
Ситуация отличается для таблиц, потому что они предназначены для реализации объектов в Lua.