lua-users home
lua-l archive

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


On Sat, 18 Apr 2015 23:21:47 -0500
Andrew Starks <andrew.starks@trms.com> wrote:

> On Saturday, April 18, 2015, Andrew Starks <andrew.starks@trms.com>
> wrote:
> 
> >
> > > [...]
> > 
> > There is one other case where nil/none appear. It almost never
> > matters, but it thwarted me from being too creative with tables:
> > __index is always adjust to one return value. So:
> >
> > __index = function(t, i, x)
> >     --x is always absent (empty/nil), btw. This would almost
> > certainly never matter, but it's true. I'm not sure how I know
> > this, actually.it wouldn't happen from trying `t[1, 2]`, because
> > that's an error. Anyway... end
> >
> > f = function()
> > end
> >
> > print (select("#", __index()), select("#", f()))
> > -->1   0
> >
> > So you can never signal the difference between nothing and `nil`
> > from your index metamethod. Again, not complaining, I'm just sayin'.
> >
> >
> Blech the above is wrong, unless you take it to mean that __index is
> being invoked as a metamethod on a table, not just a function hanging
> out in space, as the variable named __index. Sorry for the noise.



Indeed:

function __index(self, key)
  return "a", "b"
end

t = setmetatable({}, {__index=__index})

print(select("#", __index()), select("#", t.x))
-->  2       1

print(__index())
-->  a       b
-- multiple values passed to the print function, because
-- __index() is last argument

print(t.x)
-->  a
-- because t.x is expected to be a _single_ value, the list
-- of arguments is truncated



Similarly, "none" would be converted to "nil" if the __index function
returns no value *and* is invoked as a metamethod:

function __index(self, key)
  return
end

t = setmetatable({}, {__index=__index})

print(select("#", __index()), select("#", t.x))
-->  0       1

print(__index())
-->  
-- nil is not shown, because __index() may pass a variable
-- number of arguments (here: zero) to the print function
-- (__index() is the last entry in the argument list for 
-- print)

print(t.x)
-->  nil
-- because t.x is expected to be a _single_ value, nil is
-- printed

print((__index()))
-->  nil
-- also here (__index()) in parenthesis must be a single
-- value, hence nil is printed


Regards,
Jan