lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 01/05/2014 22:56, Sean Conner wrote:
It was thus said that the Great Andrew Starks once stated:
Here is a hack that I like a lot:

```lua

debug.setmetatable(nil, {
     __index = function(t, i)
         return nil
     end
})

local this = {}

if this.field.does.NOT.exist == nil then
     print('no error!')
end

--> no error!
```
   Wow.

   I'm of two minds on this.  On the one hand, I love the idea, because there
are times when I want this behavior.  On the other hand, this can hide some
serious bugs in a code base.  On the gripping hand [1], I wouldn't know how
to deal with a codebase that does this.

   -spc (I never thought that nil could have a metatable associated with it)

[1]	The two hardest things in computer science: naming, cache
	invalidation and off-by-one errors.

There's no need for a hack:

NIL_VALUE = {}
softmt = { __index = function(t,k) if rawget(t,k) == nil then return NIL_VALUE else return rawget(t,k) end end }
setmetatable(NIL_VALUE,softmt)

softtable = {}
setmetatable(softtable,softmt)

val = softtable.some.invalid.key
if val == NIL_VALUE then return "it works!" end

Best part? If you don't have a __metatable protected metatable:

oldmt = getmetatable(t)
setmetatable(t,softmt)
val = t.insert.some.long.chain.here
if val == NIL_VALUE then val = nil end
setmetatable(t,oldmt)
-- etc

While it's not as nice as Groovy[1] it does the job just fine...

[1] http://groovy.codehaus.org/Null+Object+Pattern