lua-users home
lua-l archive

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


On Sun, 9 May 2010, Klaus Ripke wrote:
>
> Could indexing anything but a table, or at least indexing nil, return
> nil instead of throwing an error? I don't see why x.z conveniently gives
> nil, if there is no z in x, but x.y.z requires an extra check for x.y .
> This makes working with structures with lots of optional parts pretty
> tedious - and if it's external input, basically everything is optional.
>
> Really I'd love to see nil behave like an empty value of
> the expected type most of the time, Perl style.

Perl's handling of nonexistent indices is more complicated than that.
If you write $x->{y}->{z} (Perl for x.y.z) then $x-{y} is autovivified
into a reference to a hash. This also applies to array references.

It isn't easy to implement this in Lua, because autovivification crosses
two layers of indirection: x.y is assigned to {} when x.y.z is used.
The following sort of approximates the way perl works, except that an
undefined index returns a new table instead of nil. Maybe Peter Cawly's
solution is good enough :-)

	autovivify_mt = {
		__index = function (t,k1)
			return setmetatable({},{
				__index = function (tk1,k2)
					t[k1] = tk1
					setmetatable(tk1, autovivify_mt)
					return tk1[k2]
				end,
				__newindex = function (tk1,k2,v)
					t[k1] = tk1
					setmetatable(tk1, autovivify_mt)
					tk1[k2] = v
				end
			})
		end
	}

	setmetatable(my_table, autovivify_mt)

Tony.
-- 
f.anthony.n.finch  <dot@dotat.at>  http://dotat.at/  【ツ】
FISHER GERMAN BIGHT: NORTH OR NORTHWEST 5 TO 7, OCCASIONALLY GALE 8 IN FISHER
AT FIRST, DECREASING 4 OR 5, BECOMING VARIABLE OR NORTHEAST 3 OR 4 LATER.
MODERATE OR ROUGH, BECOMING SLIGHT OR MODERATE. SHOWERS THEN FAIR. GOOD.