При использовании Metatables с Lua, есть ли способ для меня, чтобы определить, устанавливается ли значение или извлекается?
Я установил в моем скрипте систему "psuedo-oop", которая позволяет мне лучше взаимодействовать с данными пользователя из моего приложения. Моя система работает замечательно хорошо, за исключением того, что она не передает ссылки, она передает значения. Из-за этого, если я скажу что-то вроде:
World.Body.Parent=World.Body2
Ничего на самом деле не происходит, потому что это никогда не устанавливает Body
Родитель другого тела. Вместо этого это как бы упрощается:
World=World.Body2
(Так как World
является родителем Body
так что возвращается). Теперь, если я сделаю что-то подобное, с другой стороны:
print(World.Body.Parent.Type)
==> World
Потому что он правильно получил World
объект (будучи родителем Body
).
Теперь, имея в виду все это, есть ли какой-нибудь способ убедиться, что он передается больше по ссылке, а не по факту отправки объекта? Любые идеи были бы хорошы!
Вот соответствующий исходный код, который я использую:
local target=_G
function AddService(service)
Blank=(function(...) return end)
CreateTemporaryIndex=(function(obj)
local env_meta={
__index=(function(this, key)
if obj[key]~=nil and obj[key]~=key then
if type(obj[key]) ~= "userdata" then
return obj[key]
else
local r,i=pcall(function() Blank(obj[key].Type) end)
if r then
return CreateTemporaryIndex(obj[key])
else
return (function(...) local arg={...} table.remove(arg,1) return obj[key](obj,unpack(arg)) end)
end
end
else
local ofObj=obj:Child(key)
if ofObj~=nil then
return CreateTemporaryIndex(ofObj)
end
end
return nil
end)
}
local nRe={}
setmetatable(nRe,env_meta)
return nRe
end)
target[service.Name]=CreateTemporaryIndex(service)
end
AddService(__Environment.World)
AddService(__Environment.Players)
AddService(__Environment.Lighting)
AddService(__Environment.Environment)
1 ответ
Метаметод __index вызывается только при доступе к свойствам. Для реализации пользовательского установщика вам также необходимо определить метаметод __newindex. Вы можете найти больше информации в разделе руководства Lua, на которое я ссылаюсь.
Тем не менее, на вашем месте я бы снова подумал, действительно ли нужно все это усложнение таблицы прокси. В качестве примера одного из небольших угловых случаев, которые вы, возможно, не рассмотрели, перебор ваших сред с парами и ipairs завершится неудачей, если вы не добавите также метаметоды __ipairs и __pairs.