hello !
I have an instance of class (called obj after) who contains {w=10, h=10}.
I want access by 2 way : obj.w and obj.width.
I know about the __index function, but i don’t know how write this =/
hello !
I have an instance of class (called obj after) who contains {w=10, h=10}.
I want access by 2 way : obj.w and obj.width.
I know about the __index function, but i don’t know how write this =/
(Warning: only tested on desktop lua.)
a = {}
mt = {}
mt.__index = function(t,k)
if k == "width" then
return k.w
end
end
mt.__newindex = function(t,k,v)
if k == "width" then
rawset(t,"w",v)
else
rawset(t,k,v)
end
end
setmetatable(a,mt)
Testing:
a.w = 10
print(a.w)
print(a.width)
a.width = 20
print(a.width)
print(a.w)
(Added)
Note: if your initial object is an instance of a class then you don’t want to overwrite its metatable as I do above because it already has some useful stuff in it. So you’d need to so mt = getmetatable(a)
first instead of mt = {}
. I’d also test to see if __index
or __newindex
are blank first - I don’t remember what Codea’s class does to objects’ metatables.
Hm… am i missunderstanding you or have you just written:
w=10, h=10
without the self thing. Only the Main class variables does not have to contain self before them selves. So the only way to access he value of obj.w is to write “self.” before “w”.
I hope I understood you right
thanks a lot @Andrew_Stacey !
and @MMGames, i have write a “bad example”. A better example (with solution)
Object = class(ObjectFather) Object.sugars = {width="w", height="h"} function Object:init() ObjectFather.init(self) self.w = 10 self.h = 10 end ------------------- At the end of file ------------------- function Object:__index(k) if Object.k then return Object.k end for sugarKey, key in pairs(Object.sugars) do if k == sugarKey then return self[key] end end end function Object:__newindex(k,v) for sugarKey, value in pairs(Object.sugars) do if k == sugarKey then rawset(self, key, v) end end rawset(self, k, v) end ------------------------------------------------------- ``` Now : ~~~ obj = Object() print(obj.w, obj.width) -- > 10, 10 obj.w = 15 print(obj.width) -- > 15 ~~~
Are you sure you want the line: if Object.k then return Object.k end
? Are you setting defaults as class variables?
I think this is the last solution with a recusive system.
Object = class(ObjectFather) Object.sugars = {width="w", height="h", x="pos.x", y="pos.y"} function Object:init() ObjectFather.init(self) self.w = 10 self.h = 10 self.pos = {} self.pos.x = 0 self.pos.y = 0 end ------------------- At the end of file ------------------- function Object:__index(k) if Object[k] then return Object[k] end for sugarKey, key in pairs(Object.sugars) do if k == sugarKey then local arr = explode(".", key) if #arr == 1 then return self[key] else local result = self for _, v in pairs(arr) do result = result[v] end return result end end end end function Object:__newindex(k,v) for sugarKey, value in pairs(Object.sugars) do if k == sugarKey then local arr = explode(".", key) if #arr == 1 then rawset(self, key, v) else local result = self for _, v in pairs(arr) do beforeLastResult = result result = result[v] end rawset(beforeLastResult, arr[#arr], v) end end end rawset(self, k, v) end ------------------------------------------------------- function explode(div,str) -- credit: http://richard.warburton.it if (div=='') then return false end local pos,arr = 0,{} -- for each divider found for st,sp in function() return string.find(str,div,pos,true) end do table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider pos = sp + 1 -- Jump past current divider end table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider return arr end ```
Yes, I was just about to tell you that the class is the metatable for all of its instances so it’s enough to define Class:__index
and Class:__newindex
.
@HyroVitalyProtago Yes, that is what you do. That was the meaning behind the “Yes, I was …”. It was to be read as “I see that you’ve figured this out for yourself, but I’ll mention it anyway”.
Ah, okay. Thanks !