Snusmumriken
Ну примерно так. function Obj:test() end function Obj.test(self) end Obj = { test = function(self) end } Последнее типа создаёт создаёт табличку.
Александр
только Obj.test = function(self) end function Obj.test(self) end
Ruslan
2 и 3 не эквиваленты
2 и 3 не эквиваленты потому что не создают таблицу?
Ruslan
да
я не говорил что 1 и 2 эквивалент еще раз повторюсь без 1 например: Obj = {} function Obj.test() end эквивалент: Obj = { test = function() end }
Александр
Короче 1 и 2 не эквиваленты, т.к. в 1 сокрыта переменная и они отличны от 3, т.к. в 1 и 2 нужно, чтобы предварительно была создана Obj
Ruslan
Короче 1 и 2 не эквиваленты, т.к. в 1 сокрыта переменная и они отличны от 3, т.к. в 1 и 2 нужно, чтобы предварительно была создана Obj
ну очевидно же что она должна быть создана иначе сам по себе function Obj.test() end не валиден вы отвечаете на те вопросы которые я не задавал)
Александр
ну очевидно же что она должна быть создана иначе сам по себе function Obj.test() end не валиден вы отвечаете на те вопросы которые я не задавал)
Ну ты говоришь об эквивалентности, а эквивалентность предполагает тождество между объектами. Корректнее говорить тогда о синтаксисе объявления функций и если так, то 2 и 3 будут всё равно отличаться, т.к. в 3 ты пересоздаёшь таблицу Obj, а в 2 лишь добавляешь в таблицу функцию
Ruslan
давайте я начну сначала потрем все эти сообщения, перефразирую
Александр
т.е. проблема в том, что ты говоришь только о функции, тогда как таблица тут меняется не меньше.
Snusmumriken
Ну кароч, что имел Руслан ввиду: как можно добиться похожих результатов с некоторыми различиями.
Александр
а кстати ещё Obj = {["test"] = function() end} как вариант записи
Snusmumriken
Конечно, но тут с самого начала понятно что человек примерно понимает разницу в том что сам написал.
Snusmumriken
Карочи, не надо грубо формально интерпретировать ))
Александр
> т.к. в 3 ты пересоздаёшь таблицу Obj чтобы пересоздать - до него должен существовать старый экземпляр а там в 3 сразу создается Obj -- 3 Obj = { test = function() end }
Тебя просто синтаксис объявления функций интересовал ? т.е. что "эквивалентность", что "одинаковый результат" во всех случаях формально не достигается
Ruslan
Тебя просто синтаксис объявления функций интересовал ? т.е. что "эквивалентность", что "одинаковый результат" во всех случаях формально не достигается
да, меня интересовал в первую очередь синтаксис с формальным одинаковым результатом но технически возможно это разные вещи а именно я так и не понял почему технически в 3 вы называете пересозданием Obj я не вижу там пересоздания
Snusmumriken
Ну формально можно пилить объекты примерно так: Obj = { set = function(self, val) self.key = val end, get = function(self) return self.key end } Obj:set(10) print( Obj.get(Obj) ) --> 10 print( Obj.key ) --> 10
Snusmumriken
это то что я хотел узнать (по части ':' ) Благодарю!
Я статью написал по этому поводу в том числе. https://habr.com/ru/post/346892/
Ruslan
ну потому, что в 3 ты совмещаешь создание Obj и создание Obj.test, в первых двух ты создаёшь Obj.test только для уже существующего Obj
по этой логике получается Obj = { test1 = function() end test2 = function() end test3 = function() end } тут таблица Obj пересоздается трижды? проходя через деструктор под капотом языка?
Snusmumriken
Александр имеет ввиду, что в первых двух примерах у тебя должна была быть объявлена таблица Obj, и третий пример, при учёте уже существования такой таблицы, пересоздаёт её.
Александр
Ну да, я по сути имею в виду, что если условия одинаковые, то во всех случаях предварительно было Obj = {}, т.е. припиши ты сразу к первым двум эту строчку, то тогда я бы не предирался
Ruslan
test1.lua Obj = {} function Obj:test() end test2.lua Obj = {} function Obj.test() end test3.lua Obj = { test = function() end }
Александр
ну скомпилируй/запусти
Александр
посмотри результат
Snusmumriken
Вот теперь, когда ты добавил к первым двум случаям Obj = {}, формально запись похожа, разве что ты забыл про self если хотел идентичности, и Александру не к чему придираться )
Ruslan
Вот теперь, когда ты добавил к первым двум случаям Obj = {}, формально запись похожа, разве что ты забыл про self если хотел идентичности, и Александру не к чему придираться )
ппц) я думал это и так ясно что там Obj т.к. без него о function Obj и речи быть не может нет я не хотел идентичности между всеми 3мя только сказал что 2 и 3 идентичные (хотябы формально)
Snusmumriken
Ну вот третий вариант как бы пересоздаёт Obj если он объявлен так же как в первых двух. Кстати, если они в файлах test1 test2 и test3 объявлены глобально, то они ещё и перетирают друг друга при поочерёдном вызове, это я на всякий случай ))
Ruslan
Snusmumriken
Не совсем, у тебя полный контроль над всем, но области видимости ты определяешь local'ом. Ещё код в файле буквально выполняется как будто обёрнут в функцию: function (...) -- буквально с многоточием, сюда приходит имя модуля первым аргументом *содержимое файла* end Поэтому из require'щихся скриптов может быть ретурн.
Snusmumriken
В целом, есть специальная функция module, использующаяся примерно так: *myscript.lua* module(package.loaded, ...) function foo(x, y) return x + y end bar = {foo = 20} И когда ты делаешь require'myscript', ему в многоточие приходит "myscript", функция module добавляет его в package.loaded, устанавливает для всего кода ниже отдельную таблицу-окружение и пихает это окружение в глобальную переменную myscript. То есть ты такой: require"myscript" myscript.foo(10, 20) --> 30 myscript.bar.foo = 40 Данная технология немножко депрекейтнутая, так что внутри модулей просто делай всё локальным, а если там есть табличка с функциями и ништяками — возвращай её в конце модуля.
Ruslan
Благодарю за пояснения! Я полез вникать в мета-таблицы потомучто мне нужна была реализация Set как в питоне, нагуглил ее но мне не понравилась ее реализация) Вот и решил за одно разобраться и свою сделать)
Snusmumriken
Set как "коллекция уникальных элементов" т.е. множество?
Ruslan
https://gist.github.com/TannerRogalsky/8511136
Ruslan
Set как "коллекция уникальных элементов" т.е. множество?
да, чтобы при повторном добавлении одинакового - не дублировались
Snusmumriken
Ну просто хеш-часть табличек по дефолту примерно так и работает как сет. set = {["bar"] = true} set["foo"] = true if set["foo"] then blabla end Пихай в таблички что угодно. Удаление элемента — set["someval"] = nil. Порядок элементов правда рандомный.
Snusmumriken
Норм
Snusmumriken
local function Set() return { store = {} function Add(self, value) self.store[value] = true end function Get(self, value) return self.store[value] end function Del(self, value) self.store[value] = nil end } end
Snusmumriken
Индексов тут нет, тут индекс — хеш-значение валью. Но сету формально не нужен индекс, это чисто питоновая фишка.
Ruslan
понял, тоесть по дефолту там плавают хеши
Snusmumriken
Ну типа когда ты добавляешь элементы в сет, ты такой делаешь это в каком-то порядке, который гипотетически может быть индексом для элементов. И у питона это так, но в целом, сет это просто множество, не обязательно упорядоченное.
Snusmumriken
Можно сделать с индексами, просто операции добавления-удаления элементов будут дольше и технически сложнее.
Ruslan
Индексов тут нет, тут индекс — хеш-значение валью. Но сету формально не нужен индекс, это чисто питоновая фишка.
не, нельзя там это я просто хотел "улучшенную версию"))) по идее это ordered_dict если по питоновски (доступ по индексам)
Snusmumriken
А почему так нельзя? list={} table.insert(list, Set()) table.insert(list, Set())
Ты в список добавляешь два разных сета условно.
Snusmumriken
не, нельзя там это я просто хотел "улучшенную версию"))) по идее это ordered_dict если по питоновски (доступ по индексам)
Так я и говорю, нет тут индексов. Хеш значение валью ты можешь получить собственно через хеширование валью, например set.store["abcdef"] — вот оно захешировало abcdef и такое нашло в себе элемент сета )) Конкретные цифры хешей — внутренняя кухня.
Ruslan
Ты в список добавляешь два разных сета условно.
ссылка на таблицу там по ходу одна и таже будет
Hello, World! 🎄
И вообще зачем 2 индекса если они будут содержать ссылку на один и тот же объект (таблицу)
Ruslan
@Snusmumriken Александр Всех благодарю за пояснения! по сути я просто не допер что если function Add(self, value) вызвать через : то self передастся автоматом думал что только из под Obj:test() {self доступен}
Snusmumriken
Ну я кидал статью, там есть примеры эквивалентов двоеточия. Их всего два: для объявления функции и для вызова, и в обоих случаях просто добавляем аргумент self, и при вызове передаём саму табличку.
Ruslan
там был этот случай Obj:spam() но я успешно проигнорил его значение))) читал перед сном))
Ruslan
а статья у вас мощная надо целиком ознакомиться
Ruslan
Продублирую ссылку на вашу статью, чтоб не искали желающие почитать ее, увидев данный пост https://habr.com/ru/post/346892/
Ruslan
хранить функции в мета таблице (не в __index, а рядом с ним) с последующим доступом к ним - реально? и без getmetatable
Ruslan
типа t = setmetatable({}, {say = function() print('hello') end})
Snusmumriken
хранить функции в мета таблице (не в __index, а рядом с ним) с последующим доступом к ним - реально? и без getmetatable
t = {} t.__index = t function t:new(x, y) -- переопределение локальной переменной self -- с таблицы t на новую табличку, -- работающую "свежим объектом" self = setmetatable({}, self) self.x, self.y = x, y return self end function t:area() return self.x * self.y end function t:__tostring() return self.x .. ":" .. self.y end local o = t:new(10, 20) print( o:area() ) --> 200 print( tostring(o) ) --> "10:20" t это и таблица с методами и метатаблица в __index.
Snusmumriken
Собственно это простейший пример ооп. Хранить же просто функции в какой-то рандомной метатаблице можно, но доступ затруднён.
Ruslan
такие вот пироги вроде функция есть но вызывается она теперь не из меты)
Ruslan
Ruslan
Snusmumriken
o[area] == nil потому что у тебя не объявлена переменная area. area = "x" print( o[area] ) --> 10
Ruslan
o[area] == nil потому что у тебя не объявлена переменная area. area = "x" print( o[area] ) --> 10
да, если написать area = 'area' то o[area]) == o['area'] но суть была не в этом а в невозможности доступа к area или если t = {area = 456} то после определения function t:area() - area = 456 вытесняется
Snusmumriken
Есть к нему доступ.
Snusmumriken
o.area —> function
Snusmumriken
Понимаешь разницу между получением функции и вызовом функции?
Snusmumriken
Функция это значение. В луях. И её можно вызвать.
Ruslan
Понимаешь разницу между получением функции и вызовом функции?
блин, вот это я тупанул) не, не тупанул print(o.area) --> 123 print(o.area()) --> attempt to call field 'area' (a number value)