Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 05:56 PM |
| What I mean when I say 'lock' is make it read-only. I've heard of this being done b4. |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 05:57 PM |
osht
I just thought of this..
local a = setmetatable({},{__newindex = function(self,i) table.remove(self,i) end})
nevermind lol |
|
|
| Report Abuse |
|
|
|
| 10 Jun 2015 05:58 PM |
...
just create one table when indexed returns values from another and make the newindex function return nil or error or whatever. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 06:39 PM |
metamethods are fallbacks so if there was no value to begin with, it is invoked but the value itself is not added, you would have to add it meanig you don't even need to table.remove (and that'll only work for array indexes anyways).
So really: setmetatable(tbl, {__newindex = function() print("No"); end;}); Is enough.
Although they can always use rawset and table.insert to add into the table bypassing __newindex, so just create a new userdata with a metatable (newproxy(true)) and there you go, just lock the metatable and do all your fancy stuff (like properties and methods) in __index |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 06:50 PM |
local table = setmetatable({},{__index=table}) table.insert = function(tab,val) tab[#tab] = val end
table.insert fixed. |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 06:51 PM |
local table = setmetatable({},{__index=table}) table.insert = function(tab,val) tab[#tab+1] = val end
Lol now it's fixed |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 06:56 PM |
| That's not how table.insert works, it also pushes all the vlaue right if you give it the optional index argument. Also why redefine t.insert? |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 06:56 PM |
| Because it uses rawset lol |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 06:58 PM |
Well I was thinking more like:
do local old = table.insert table.insert = function(t, k, v) if getmetatable(t) ~= "locked" then old(t, k, v); end end; end
So you just set the __metatable of your table to "locked" |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 06:59 PM |
| __metatable of your table's metatable** |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
| |
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 07:12 PM |
Now how would I overwrite metatables? Since i'd want to unlock a table as well.
|
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 07:13 PM |
Ooh nvm I can just do
local a = setmetatable({},{__metatable='locked'}) getmetatable(a).__metatable = getmetatable(a) |
|
|
| Report Abuse |
|
|
Lecturous
|
  |
| Joined: 17 Aug 2013 |
| Total Posts: 1096 |
|
|
| 10 Jun 2015 07:27 PM |
"Ooh nvm I can just do
local a = setmetatable({},{__metatable='locked'}) getmetatable(a).__metatable = getmetatable(a)"
Wouldn't that error? If you try getmetatable of a, that would return the string 'locked', and then you try to set the __metatable of 'locked' to 'locked'. I think? |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 07:40 PM |
ur right..
ljsnefuhsrandon
How would I overwrite a metatable?[2] |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 07:41 PM |
| You can't, that ruins the point of the __metatable metamethod. |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 07:51 PM |
So then a table.unlock function is impossible? Unless I somehow externally referenced the metatable then replicate the table into a new table, and set the referenced metatable without the __metatable index..
local tab = {} local meta = {__newindex = function() print'new' end} setmetatable(tab,meta)
table.unlock = function(t) local new = {} for i,v in pairs(t) do new[i] = v end setmetatable(new,meta) end
But that's not vurry good.. ehhhhhh..... maybe table.unlock juss isn't possibrooh |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 07:55 PM |
You can't re-set a metatable if __metatable is set also :) You can't unlock it if __metatable is set, although you can create a new table I guess and hold a reference to the metatable before it's locked so you can 'restore' all the metamethods (other than __metatable obviously) |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 08:18 PM |
Hmm.. i'm wondering how to make a reference to a table's set metatable whenever one is set..
I can't set an index inside the metatable since the whole point is __metatable is a biachh so liek.. ehh.. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 08:23 PM |
Just define __metatable after having a ref., for example:
local tbl = {}; setmetatble(tbl, {blah without __metatable}); local ref = getmetatable(tbl); ref.__metatable = "locked"; |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 08:58 PM |
Ohthx. But where to store that in a way that table.unlock could be used?
Perhaps alternative dictionary, with keys of the table name..
local mets = {} local tbl = {}
table.lock = function(tab) setmetatble(tab, {}) local ref = getmetatable(tab) ref.__metatable = "locked" mets[tostring(tab)] = ref end
table.unlock = function(tab) local new = setmetatable({},mets[tostring(tab)]) for i,v in pairs(tab) do new[i] = v end end
But then if there's a __tostring index when table.lock is used then it could call some stuff, I guess that doesn't really matter though.
Thanks for the help! |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 09:00 PM |
| Fek, if a __tostring index is set to return a value then this system could be messed up. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 10 Jun 2015 09:29 PM |
Considering all the locked tables' metatables are going to be the same, it wouldn't be hard, will it ever be different?
Also I have a very different and better approach to this (more memory friendly and we can restore the actual table they use instead of a 'clone' or whatever.) |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 10:00 PM |
| Well the point is for an extended library, so people could potentially set their own metatables. So no, all the metatables will *not* be the same. |
|
|
| Report Abuse |
|
|
Goulstem
|
  |
| Joined: 04 Jul 2012 |
| Total Posts: 7177 |
|
|
| 10 Jun 2015 10:53 PM |
| Any solutions to make it so the __tostring index can't potentially break the lock/unlock system? I'd hate to have to settle for that. |
|
|
| Report Abuse |
|
|