lua-users home
lua-l archive

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


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)


__________________________________