[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [hack] nil.foo = nil
- From: Andrew Starks <andrew.starks@...>
- Date: Thu, 1 May 2014 21:23:57 -0500
On Thursday, May 1, 2014, Thiago L. <fakedme@gmail.com> wrote:
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
The thing is, this hack works with every table in existence, not just ones that don't have an __index method that is available for override.
The trouble(?) is, it works with nothing, too:
local foo = nil
print(foo.bar)--> nil
It kind of breaks my brain. I'm not near a real computer, so I'll have to try out what happens when a table with __index assigned to a table returns nil... Does the rawget kill the fun? It might not... Probably need more sleep to hypothesize. :)
-Andrew