3 ms·
> In Lua, it's impossible to have a dictionary that maps a key to nil: setting a key to nil removes it from the dictionary! Wait is he really trying to say, "S
by tieTYT 12y ago
> In Lua, it's impossible to have a dictionary that maps a key to nil: setting a key to nil removes it from the dictionary!
Wait is he really trying to say, "Setting a VALUE to nil removes the entry from the dictionary!"? If so, that sounds terrible.
I can imagine barking up the wrong tree wondering why my map is missing fields when the real problem is an object I passed into it is unexpectedly nil.
- rntz 12y agoYes, that is what I meant. And yeah, it is weird behavior. (I think of "d[k] = v" as "setting the key k to the value v", so that's why I said "setting a key". Perhaps "binding a key" would be clearer?)
- deleted 12y ago[deleted]
- russellsprouts 12y agoYes, that's true. It does have drawbacks, but overall I think it is better than say, JavaScript. In JavaScript, a key can be not present in an object, be undefined, be null, be set to some other value, or be present in the prototype. The difference between these can cause very subtle bugs. //Let's define some object var obj = {a: true, b: true, c: true, d: true, hasOwnProperty: true} //Now let's make them falsy in different ways obj.a = undefined; //set to undefined obj.b = null; //set to null obj.c = false; //set to false delete obj.d; //delete key delete obj.hasOwnProperty //delete key, but present in prototype console.log(obj.a) //--> undefined console.log(obj.b) //--> null console.log(obj.c) //--> false console.log(obj.d) //--> undefined console.log(obj.hasOwnProperty) //--> [Function] console.log('a' in obj) //--> true console.log('b' in obj) //--> true console.log('c' in obj) //--> true console.log('d' in obj) //--> false console.log('hasOwnProperty' in obj) //--> true console.log(obj.a == null) //--> true console.log(obj.b == null) //--> true console.log(obj.c == null) //--> false console.log(obj.d == null) //--> true console.log(obj.hasOwnProperty == null) //--> false for(var key in obj) { console.log(key) //--> prints a, b, c } In Lua, the only data structure is a hashtable, which maps any non-nil value to any other non-nil value. It can also be set in the objects __index metamethod/table local tab = {a = true, b = true, c = true} -- by default there are none, but we can defined a fallback metatable similar to a prototype method like js's obj.prototype.hasOwnProperty setmetatable(tab, {__index={c='meta c', d='meta d'}}) -- if it is important that a key is explicitly set to false, do so, otherwise simply remove it tab.a = false --set to false tab.b = nil --set to nil tab.c = nil --set to nil, present in fallback table tab.d = false --set to false, present in fallback table print(tab.a) --false print(tab.b) --nil print(tab.c) --meta c print(tab.d) --false The rules for Lua are simple: Look for the key in the table, if it's not there, check the fallback defined in the metatable, if not, then return nil. This is especially important in Lua, because any value can be a key, you would have to be sure to delete the key otherwise it could not be garbage collected. local tab1 = {1,2,3,4,5} local tab2 = {} tab2[tab1] = true for k,v in pairs(tab2) do tab[k] = nil end If this worked like JavaScript, then tab2[tab1] would return nil, but tab1 could not be garbage collected until tab2 is. Because JavaScript objects can only have strings for keys, this is less of an issue.