This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

28.4 – Array Access

An alternative to the object-oriented notation is to use a regular array notation to access our arrays. Instead of writing a:get(i), we could simply write a[i]. For our example, this is easy to do, because our functions setarray and getarray already receive their arguments in the order that they are given to the respective metamethods. A quick solution is to define those metamethods right into our Lua code:

    local metaarray = getmetatable(newarray(1))
    metaarray.__index = array.get
    metaarray.__newindex = array.set
(We must run that code on the original implementation for arrays, without the modifications for object-oriented access.) That is all we need to use the usual syntax:
    a =
    a[10] = 3.4         -- setarray
    print(a[10])        -- getarray   --> 3.4

If we prefer, we can register those metamethods in our C code. For that, we change again our initialization function:

    int luaopen_array (lua_State *L) {
      luaL_newmetatable(L, "LuaBook.array");
      luaL_openlib(L, "array", arraylib, 0);
      /* now the stack has the metatable at index 1 and
         `array' at index 2 */
      lua_pushstring(L, "__index");
      lua_pushstring(L, "get");
      lua_gettable(L, 2);  /* get array.get */
      lua_settable(L, 1);  /* metatable.__index = array.get */
      lua_pushstring(L, "__newindex");
      lua_pushstring(L, "set");
      lua_gettable(L, 2); /* get array.set */
      lua_settable(L, 1); /* metatable.__newindex = array.set */
      return 0;