Size: a a a

2019 August 21

CP

Companion Philipp in pro.lua
Сегодня пытался придумать адекватную прокси-табличку, которая бы была оберткой над модулем, чтобы при отсутствии модуля не падать с attempt to index a nil value, но в итоге взгрустнул, что все варианты адекватно предусмотреть не получится (или я глупый).

Ну чот типа такого.
Исходный модуль CoolModule. Вызов какой-нибудь функции CoolModule.MyFunc(). Получение какой-нибудь константы CoolModule.CONST. И вот в некоторых случаях этого модуля может не быть. И хочется избавиться от проверок а-ля if CoolModule then … end
источник

CP

Companion Philipp in pro.lua
Не то чтобы это вопрос (задачу решил иначе), но вдруг Снус скажет что я дурак и забыл, что как-то можно было подхачить :)
источник

МК

Марк ☢️ Коренберг in pro.lua
источник

CP

Companion Philipp in pro.lua
Переопределить __index и навесить туда логику по типу
__index = function(t, k) if CoolModule then return CoolModule[k] else return bla end

Не получается, ибо перестает работать, если мы дергаем функции CoolModule, ибо Attempt to call a nil value
источник

S

Snusmumriken in pro.lua
Companion Philipp
Сегодня пытался придумать адекватную прокси-табличку, которая бы была оберткой над модулем, чтобы при отсутствии модуля не падать с attempt to index a nil value, но в итоге взгрустнул, что все варианты адекватно предусмотреть не получится (или я глупый).

Ну чот типа такого.
Исходный модуль CoolModule. Вызов какой-нибудь функции CoolModule.MyFunc(). Получение какой-нибудь константы CoolModule.CONST. И вот в некоторых случаях этого модуля может не быть. И хочется избавиться от проверок а-ля if CoolModule then … end
А это смотря что ты делаешь со значениями ключей, которые не можешь найти.
Ну класека —

local MyTable = {}

local mt = {}
function mt:__index(key)
 return rawget(self, key) or "Nothing here"
end

setmetatable(mt, MyTable)

Другое дело что возвращаемое "дефолтное значение" может быть только одного типа. Но можно извратиться:

local MyTable = {}

local emptyProxy = {}
local mt = {}

setmetatable(emptyProxy, mt)


function mt:__tostring()
 return "nothing here"
end

function mt:__concat(v)
 return tostring(self) .. tostring(v)
end

function mt:__call()
 return "empty func"
end

-- рекурсия, о да
function mt.__index(...)
 return rawget(...) or emptyProxy
end

function mt:__add(v)
 return self == emptyProxy and v or self
end

mt.__sub = mt.__add
mt.__mul = mt.__add
mt.__div = mt.__add

setmetatable(MyTable, {__index = mt.__index})

Эту "дефолтную таблицу" можно вызывать как функцию, складывать, вычитать, конкатенировать и она работает типа как "дефолтное пустое значение с которым делайте что хотите, ничо не будет"
источник

CP

Companion Philipp in pro.lua
Snusmumriken
А это смотря что ты делаешь со значениями ключей, которые не можешь найти.
Ну класека —

local MyTable = {}

local mt = {}
function mt:__index(key)
 return rawget(self, key) or "Nothing here"
end

setmetatable(mt, MyTable)

Другое дело что возвращаемое "дефолтное значение" может быть только одного типа. Но можно извратиться:

local MyTable = {}

local emptyProxy = {}
local mt = {}

setmetatable(emptyProxy, mt)


function mt:__tostring()
 return "nothing here"
end

function mt:__concat(v)
 return tostring(self) .. tostring(v)
end

function mt:__call()
 return "empty func"
end

-- рекурсия, о да
function mt.__index(...)
 return rawget(...) or emptyProxy
end

function mt:__add(v)
 return self == emptyProxy and v or self
end

mt.__sub = mt.__add
mt.__mul = mt.__add
mt.__div = mt.__add

setmetatable(MyTable, {__index = mt.__index})

Эту "дефолтную таблицу" можно вызывать как функцию, складывать, вычитать, конкатенировать и она работает типа как "дефолтное пустое значение с которым делайте что хотите, ничо не будет"
М, да. За второй вариант спасибо, я забыл как-то о нём
источник

CP

Companion Philipp in pro.lua
Но в итоге, пока кода мало, ограничился (хотя и не хотел) проверками if CoolModule then
источник

S

Snusmumriken in pro.lua
А ещё есть pcall, кек
источник

CP

Companion Philipp in pro.lua
pcall защищает от attempt to index/call a nil value?
источник

S

Snusmumriken in pro.lua
Ещё как
источник

CP

Companion Philipp in pro.lua
А, точно
источник

CP

Companion Philipp in pro.lua
(простите, я в последнее время маловато пишу на Lua системные весчи)
источник

S

Snusmumriken in pro.lua
Он защищает даже от части ошибок на сишной стороне (когда рейзится еррор)
источник

CP

Companion Philipp in pro.lua
Ага, вспомнил, спасибо
источник

S

Snusmumriken in pro.lua
Companion Philipp
Ага, вспомнил, спасибо
Блин, допилил прокси-таблицу, теперь можно неограниченно дёргать ключи рекурсивно, хоть так: MyTable.Foo.Bar(), даже если никаких Foo и Bar нету. Давно не делал такие адовые хаки.
источник

CP

Companion Philipp in pro.lua
Snusmumriken
Блин, допилил прокси-таблицу, теперь можно неограниченно дёргать ключи рекурсивно, хоть так: MyTable.Foo.Bar(), даже если никаких Foo и Bar нету. Давно не делал такие адовые хаки.
Круто же :-)
источник

CP

Companion Philipp in pro.lua
Универсальный safe-wrapper для неоднозначно подгруженных модулей
источник

S

Snusmumriken in pro.lua
Единственная проблема — тип возвращаемого значения всё равно таблица, могут ругаться некоторые функции, типа "хуле ты сюда таблицу сунул", особенно сишные с проверкой аргументов. Но тут я уже не помогу. Но делать с этой таблицей можно что угодно.
источник

МК

Марк ☢️ Коренберг in pro.lua
источник

МК

Марк ☢️ Коренберг in pro.lua
Этот бот у меет в капчу
источник