[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Definition of table.insert
- From: steve donovan <steve.j.donovan@...>
- Date: Tue, 11 Jan 2011 13:59:02 +0200
On Tue, Jan 11, 2011 at 10:30 AM, Dirk Laurie <dpl@sun.ac.za> wrote:
> 2. nil is not a first-class value and may therefore not be either
> a key or a value.
And here's another 'special' property of nil: it is considered to mark
the end of an iterator. So simple single-valued sequences may not
contain nil.
It would be convenient to have an animal called 'nada', which behaves
like nil, except in a table context (Mark Hamburg has made such a
suggestion, but was shot down for trying to introduce a null/undefined
distinction from JavaScript).
You can _almost_ implement nada in Lua
local MT = { }
function MT:__index(k)
error('cannot index nil',2)
end;
MT.__newindex = MT.__index
function MT:__call()
error('cannot call nil',2)
end
function MT:__tostring()
return 'nil'
end
function MT.__eq(a,b)
local ta = type(a)
return ta=='nil' or ta=='table'
end
nada = {}
setmetatable(nada,MT)
debug.setmetatable(nil,MT)
So the naive idea was that nil == nada because they share a metatable,
but that's not how __eq works. According to the manual __eq logic does
this:
if type(op1) ~= type(op2) then return nil end
local mm1 = metatable(op1)['__eq']
local mm2 = metatable(op2)['__eq']]
if mm1 == mm2 then return mm1 else return nil end
The type() check knocks us out directly, but notice that the logic is
not 'have the same metatable', it is 'may have different metatables
that share the same __eq'. This subtle difference makes __eq play nice
with inheritance.
Yes, a __type metamethod would be nice (especially if it can work on
this level) but I imagine it would make type() more expensive.
So, without __eq, one still has to check whether a value is nil or
nada, but in other respects it behaves the same and is a useful
non-hole value to put into arrays of objects.
steve d.