lua-users home
lua-l archive

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


  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 <>
Subject: Re: Metatable __index issues
To: Lua list <>
Message-ID: <>
Content-Type: text/plain; charset=us-ascii

--- Tim Conkling <> wrote:
> Why doesn't the __index metamethod get called when I access
> table.var? The reference manual simply says '"index": the
> 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)

proxy_metatable.__newindex = 
  function(table, key, value) 

function make_readonly(table)
  local proxy = {}
  proxy_metatable[proxy] = table
  setmetatable(proxy, proxy_metatable)
  return proxy

-- 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)