🐅🤦♂️
эм... почему тогда nil?
Не хватает поля __index в табличке, которая устанавливается как мета. Нет метаметода - нет эффекта
Ameliance
Ameliance
хотя нет, не в книге, а в мануале официальном
Ameliance
что происходит если вызвать эту функцию?setmetatable(megalamp, superlamp)
можно ли ее как-то перефразировать по другому, то есть что она из себя представляет изнутри?
Igor
setmetable не имеет альтернатив на уровне lua, она добавляет метаметоды из метатаблице к твоей таблице, которую ты передаёшь первым аргументом. Метатаблица - это такая штука, которая может содержать в себе переопределения операторов, к прмеру или ключ индексирования, который будет ссылаться на таблицу, в которой Lua будет искать ключи при обращении к оригинальной таблице, которой назначена метатаблица.
Ameliance
пока просто в моей логике я посылаю 2 таблицы и она одну привязывает к другой в качестве метатаблицы
Igor
local meta = {
__mul = function(a, b)return a.val * b end
}
local mytab = setmetatable({val = 10}, meta)
print(mytab * 5) -- вернёт 50
Igor
Это переопределение оператора умножения для таблицы
Igor
Полный список метаметодов есть в документации
Igor
когда ты указываешь в метатаблице ключ __index и даёшь ему значение с ссылкой на саму метатаблицу, ты говоришь интерпрератору, что когда происходит обращение к методу оригианльной таблицы, его нужно искать в метатаблице
Igor
local meta = {
test = function(a, b)return a.val * b end
}
meta.__index = meta
local mytab = setmetatable({val = 10}, meta)
print(mytab:test(5))
Ivan
Прочитай книгу =) Там все очень подробно рассказывается что такое метатаблицы, зачем они, что можно с ними делать.
Ivan
https://www.ozon.ru/context/detail/id/135559046/
Igor
Почти тоже самое, что в первом варианте, но без переопределния метаметода умножения, создаётся функция test внутри метатаблицы, к которой происходит обращение из основоной таблицы
Igor
Про них как раз лучше почитать, да, а то судя по вопросам вообще нет понимания, что такое метатаблицы и с чем их едят
Ameliance
Igor
Тем, что во втором варианте в метатаблице ссылка будет на другую таблицу и с помощью неё будет индексироваться superlamp
Igor
В обоих случаях индексация происходит через таблицу lamp, но во втором создаётся ещё одна, которая является только метстаблицей и не является индексируемой
Igor
Во втором случае метатаблица может содержать только метаметоды, если проще говорить
Igor
Вам проще прочитать PiL, тогда всё встанет на свои места, там объясняется подробнее
Ameliance
просто в моем коде если я пишу вариант 1. или 2. не происходит никакой разницы...
Ameliance
я уже запарился😢
Ivan
глава 13, страница 156 "Метатаблицы и метаметоды"
Ameliance
Ameliance
Метатаблица — это таблица где собраны все возможные операции с значением (переменной, текстом, функцией... а в данном случае с таблицей )?
То есть метатаблица это набор (таблица) метаметодов (функций) которые выполняются когда мы хотим что-то сделать со значением?
То есть
a = 5
b = 10
c = a + b
означает
c = c.__add(a, b)
и в итоге
c = a + b
выдаст с = 15
А если сделать так
setmetatable(с, {__add = function(a, b) return a - b end})
то
c = a + b
будет с = -5, а
d = a + b
по прежнему будет d = 10
?
Ameliance
я так понимаю я уже ближе?
Вопрос если здесь написать то «родительскую таблицу цифер» (подскажите где найти), то у меня получится сделать, что + будет вычитать?родительскую таблицу строки
Igor
Igor
У чисел нет метатаблиц, getmetstable('вообщечтоугодно') вернёт метатаблицу строки
Snusmumriken
Поправка.
То есть
a = 5
b = 10
c = a + b
означает
c = a.__add(a, b)
мы складываем a и b, должен вызваться метаметод у a
А если у a нет метатаблицы, а у b есть, то вообще будет вызвано
c = b.__add(a, b)
Но у чисел действительно нет метатаблиц, это бы вызвалось будь a или b таблицей/cdata с метаметодом.
Ameliance
Это так не работает
это я понял, потому и написал «подскажите где найти»... и да, где-то видел в интернете запрос на добавление этой функции, но не был в курсе добавили ли
Ameliance
Snusmumriken
a = {}
b = {}
setmetatable(a, b)
Ничего не изменилось. a не стало где-то доискивать ключи, потому что у b нет специальных полей.
Добавим в b поле __index и a начнёт доискивать по этому полю ключи. Удалим это поле — перестанет. Добавим — начнёт, удалим — перестанет.
Добавим в b поле __add с функцией — и a можно будет складывать со всякой фигнёй. Удалим — нельзя будет складывать.
Вся суть метатаблиц — в специальных полях. Без полей они бесполезны.
Igor
Я что-то заметил, что почти всем трудно даются метатаблицы.
Ameliance
Snusmumriken
Когда мы хотим что-то сделать с таблицей, у которой есть эта метатаблица. Да.
Snusmumriken
Определяются перегрузки операторов и всякая специальная фигня.
Ivan
Snusmumriken
Snusmumriken
Snusmumriken
В целом, метатаблицу можно прицепить к трём типам: к таблицам, к cdata и к строкам. Но строки мы пока отметаем, пусть работают как работают, они и так хороши.
Arslan
Snusmumriken
Всмысли? Он там и так есть. Натравлен на таблицу string.
Snusmumriken
local a = "qwerty"
print( a:sub(3, 3) ) --> "e"
Строки — уже с метатаблицей, в которой есть __index.
Arslan
В смысле обращение к символу в строке через оператор []
Snusmumriken
Это бешеный оверхед.
Snusmumriken
Во-первых, это нехило замедляет доступ к обычным методам строки, во-вторых — оверхед.
В третьих — это будет обращение к байту а не к символу, если встраивать utf8 с обращением именно к юникод-символу — оно будет ещё медленнее ))
Кароч, игра не стоит свеч.
Snusmumriken
А в четвёртых — это изменение поведения стандартной библиотеки. Что является весьма нехорошим делом.
Arslan
А если через __call сделать?
Snusmumriken
Ой-ой ))
Arslan
Он же не используется
Snusmumriken
Гипотетически — конечно можно. Но всё равно не надо.
Представь что ты опечатался, и вместо функции послал в качестве какого-нибудь колбека строку. И его начали вызывать со странными аргументами (колбековыми), и всё падает, весьма громко но очень непонятно ))
Igor
Это прям что-то совсем жуткое
Snusmumriken
Когда я был маленький, мне тоже хотелось всё расширять и поливать сиропом синтаксического сахара. А потом я такой увидел, что код превращается во что-то странное, типа:
local a = foo"blabla"{bar = 123}"foo""bar"
В луа можно так делать. Но не нужно ))
Arslan
Ох ох
Arslan
Это как?
Igor
Я одно время для метатаблицы строк определял __add, чтобы их конкатить, но потом произвёл замеры времени исполнения своего оператора и стандартной конкатенации и что-то перехотел таким заниматься
Snusmumriken
Это как?
Функция foo вызывается со строкой "blabla", и возвращает функцию, которая принимает первым аргументом таблицу, и возвращает функцию, которая принимает строку "foo"..
Arslan
Ухты
Arslan
И даже скобки расставлять не нужно
Snusmumriken
Всё за счёт сахара
require"mylib" — если функция принимает одну строку или таблицу, скобки не нужны. А там — просто вызов возвращаемых функций по цепочке.
Snusmumriken
Но разбираться в этом и отлаживать — адовый ад.
Arslan
Arslan
В lua тоже придется привыкать
Snusmumriken
У луа и php, конкатенация и оператор сложения _намеренно_ разделены, чтобы не было как в JS:
Igor
Я одно время с php долго тёрки вёл
Igor
Но это было давно и вообще неправда
Arslan
Ameliance
что-то из этого является метатаблицей?
что-то из этого является частью (то из чего состоит) метатаблица?
Snusmumriken
Это очень интересный вопрос, потому что я вижу только таблицу "tab", и ни одной метатаблицы, только висящие в воздухе имена метатабличных полей и операторы ))
Ameliance
Ameliance
Snusmumriken
Нене, даже не смотри на эту фигню, запутаешься лишний раз.
Snusmumriken
Просто запомни, что в твоём случае — метатаблицы влияют ТОЛЬКО на таблицы. Как дорастёшь до cdata — будешь ещё цеплять их туда.
Ameliance
у чего по умолчанию есть метатаблица?
Snusmumriken
Только строки. У них уже сразу есть метатаблица, но это внутренности языка, тебя это не должно интересовать.
Так что считай что ни у чего нет метатаблиц по умолчанию.