[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Metatable __index issues
- From: Vinicius da Silva Almendra <almendra@...>
- Date: Mon, 18 Aug 2003 12:38:05 -0300 (BRT)
Hello,
I found out what seems to be a bug (correct me if I'm wrong...) in Lua5:
when setting numeric indices in a table, the __index metamethod is called
whether or not the field has an associated value.
Best regards,
Vinicius Almendra
TeCGraf researcher
----------------
Original Message
----------------
Date: Fri, 15 Aug 2003 23:07:15 -0700 (PDT)
From: Eric Tetz <erictetz@yahoo.com>
Subject: Re: Metatable __index issues
To: Lua list <lua@bazar2.conectiva.com.br>
Message-ID: <20030816060715.25064.qmail@web40306.mail.yahoo.com>
Content-Type: text/plain; charset=us-ascii
--- Tim Conkling <tconkling@brown.edu> wrote:
> Why doesn't the __index metamethod get called when I access
> table.var? The reference manual simply says '"index": the
indexing
> access table[key]' to describe when this function gets called.
Yeah, the manual's one-liner synopsis is misleading, but the
synposis is followed by clarifiying pseudocode (lua code actually):
if type(table) == "table" then
local v = rawget(table, key)
if v ~= nil then return v end
...
In other words, __index metamethod is only called if 'key' does not
exist in the table.
> I am trying to protect a table from being modified, and I thought
> the best way to do this would be through metatables
Well, since __index is called if 'key' doesn't exist, you could use
a stand-in for the table that has no keys:
local proxy_metatable = {}
proxy_metatable.__index =
function(proxy, key)
return rawget(getmetatable(proxy)[proxy], key)
end
proxy_metatable.__newindex =
function(table, key, value)
end
function make_readonly(table)
local proxy = {}
proxy_metatable[proxy] = table
setmetatable(proxy, proxy_metatable)
return proxy
end
-----------------
-- Example usage:
-----------------
t = {}
t.a = "apple"
t.b = "ball"
t = make_readonly(t)
print(t.a, t.b)
t.a = "ardvaark"
t.b = "bat"
print(t.a, t.b)
__________________________________