lua-users home
lua-l archive

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


On Sat, Jul 11, 2015 at 6:46 AM, Seba <lseba@icloud.com> wrote:
> Hello!
>
> I'm currently diving into Lua's C API, and try to set up an example "shapes"
> library that allows me to create shapes (such as rectangles, triangles,
> etc.), and use methods on them, such as "get_width()" and similar.
>
> This is the way I would like to use the library:
>
> shapes = require "shapes"
>
> rect = shapes.rectangle.new()
> print(rect:get_width())
>
> tri = shapes.triangle.new()
> print(tri:get_width())
>
>
> Chapter 29 of PIL teaches me how to set up a single "rectangle" table that I
> can use like this:
>
> shapes = require "shapes"
>
> rect = shapes.new()
> print(rect:get_width())
>
> Using the following C code:
>
> /* ... */
>
> int luaopen_shapes(lua_State *L) {
>     luaL_newmetatable(L, "rectangle");
>     luaL_setfuncs(L, rectangle_m, 0);
>     luaL_newlib(L, rectangle_f);
>     return 1;
> }
>
>
> However, I'm unsure how I can put my separate "triangle" and "rectangle"
> tables into a parent table. All examples I've found so far either use a
> single table (like "shapes.new()" instead of "shapes.rectangle.new()") or
> use functions prior to Lua 5.2. However, I would like to know how to do this
> in Lua 5.2/5.3 that don't support luaL_register() anymore (as far as I
> understand).
>
> I had some luck using the following setup inside luaopen_shapes():
>
> lua_newtable(L);
> luaL_newmetatable(L, "rectangle");
> luaL_setfuncs(L, rectangle_m, 0);
> luaL_newlib(L, rectangle_f);
> lua_setfield(L, -2, "rectangle");
>
>
> However, when I create an object using "shapes.rectangle.new()" this way, I
> can't access it's methods: rectangle:get_width()
>
> I probably put the tables and metatables on the stack in a wrong order. I
> would be very grateful if someone could show me the right order.
>
> Kind regards
>

Actually, your problem doesn't have anything to do with how you're
using the C API. You've simply made a mistake in how your metatable is
constructed. Look at the "Table-Access Metamethods" section in PiL.

Your "rectangle" table currently looks like { new = --[[some
function]], get_width = --[[some function]] }.

However, what you ACTUALLY want is { new = --[[some function]],
__index = { get_width = --[[some function]] } }.

(Also make sure that you're calling setmetatable on the object you're
creating inside rectangle.new.)

/s/ Adam