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
да
я не говорил что 1 и 2 эквивалент
еще раз повторюсь без 1
например:
Obj = {}
function Obj.test()
end
эквивалент:
Obj = {
test = function()
end
}
Александр
Александр
Короче 1 и 2 не эквиваленты, т.к. в 1 сокрыта переменная и они отличны от 3, т.к. в 1 и 2 нужно, чтобы предварительно была создана Obj
Ruslan
давайте я начну сначала
потрем все эти сообщения, перефразирую
Александр
т.е. проблема в том, что ты говоришь только о функции, тогда как таблица тут меняется не меньше.
Snusmumriken
Ну кароч, что имел Руслан ввиду: как можно добиться похожих результатов с некоторыми различиями.
Александр
а кстати ещё Obj = {["test"] = function() end} как вариант записи
Ruslan
Александр
Snusmumriken
Конечно, но тут с самого начала понятно что человек примерно понимает разницу в том что сам написал.
Snusmumriken
Карочи, не надо грубо формально интерпретировать ))
Александр
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
Ruslan
Александр
Александр
Snusmumriken
Александр имеет ввиду, что в первых двух примерах у тебя должна была быть объявлена таблица Obj, и третий пример, при учёте уже существования такой таблицы, пересоздаёт её.
Александр
Ну да, я по сути имею в виду, что если условия одинаковые, то во всех случаях предварительно было Obj = {}, т.е. припиши ты сразу к первым двум эту строчку, то тогда я бы не предирался
Ruslan
Ruslan
test1.lua
Obj = {}
function Obj:test()
end
test2.lua
Obj = {}
function Obj.test()
end
test3.lua
Obj = {
test = function()
end
}
Александр
ну скомпилируй/запусти
Александр
посмотри результат
Snusmumriken
Вот теперь, когда ты добавил к первым двум случаям Obj = {}, формально запись похожа, разве что ты забыл про self если хотел идентичности, и Александру не к чему придираться )
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
Snusmumriken
Ну просто хеш-часть табличек по дефолту примерно так и работает как сет.
set = {["bar"] = true}
set["foo"] = true
if set["foo"] then blabla end
Пихай в таблички что угодно. Удаление элемента — set["someval"] = nil.
Порядок элементов правда рандомный.
Snusmumriken
Норм
Ruslan
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
Ruslan
Snusmumriken
Индексов тут нет, тут индекс — хеш-значение валью.
Но сету формально не нужен индекс, это чисто питоновая фишка.
Ruslan
понял, тоесть по дефолту там плавают хеши
Hello, World! 🎄
Snusmumriken
Ну типа когда ты добавляешь элементы в сет, ты такой делаешь это в каком-то порядке, который гипотетически может быть индексом для элементов. И у питона это так, но в целом, сет это просто множество, не обязательно упорядоченное.
Hello, World! 🎄
Snusmumriken
Можно сделать с индексами, просто операции добавления-удаления элементов будут дольше и технически сложнее.
Snusmumriken
Hello, World! 🎄
Hello, World! 🎄
И вообще зачем 2 индекса если они будут содержать ссылку на один и тот же объект (таблицу)
Ruslan
@Snusmumriken Александр
Всех благодарю за пояснения!
по сути я просто не допер что если
function Add(self, value)
вызвать через : то self передастся автоматом
думал что только из под Obj:test() {self доступен}
Snusmumriken
Ну я кидал статью, там есть примеры эквивалентов двоеточия. Их всего два: для объявления функции и для вызова, и в обоих случаях просто добавляем аргумент self, и при вызове передаём саму табличку.
Ruslan
Ruslan
там был этот случай Obj:spam()
но я успешно проигнорил его значение)))
читал перед сном))
Ruslan
а статья у вас мощная
надо целиком ознакомиться
Ruslan
Продублирую ссылку на вашу статью, чтоб не искали желающие почитать ее, увидев данный пост
https://habr.com/ru/post/346892/
Александр
Александр
Ruslan
хранить функции в мета таблице (не в __index, а рядом с ним) с последующим доступом к ним - реально? и без getmetatable
Ruslan
типа
t = setmetatable({}, {say = function() print('hello') end})
Snusmumriken
Собственно это простейший пример ооп.
Хранить же просто функции в какой-то рандомной метатаблице можно, но доступ затруднён.
Ruslan
такие вот пироги
вроде функция есть но вызывается она теперь не из меты)
Ruslan
Ruslan
Snusmumriken
o[area] == nil потому что у тебя не объявлена переменная area.
area = "x"
print( o[area] ) --> 10
Snusmumriken
Есть к нему доступ.
Snusmumriken
o.area —> function
Snusmumriken
Понимаешь разницу между получением функции и вызовом функции?
Snusmumriken
Функция это значение. В луях. И её можно вызвать.