lua-users home
lua-l archive

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


2008/7/27 E. Wing <ewmailing@gmail.com>:
> Currently, I can create my userdata in Lua and I have written the
> __index and __newindex metamethods so I can access the elements as in
> the following in Lua:
>
> local my_matrix = matrix.MyMatrixFromLua(1, 2, 3, 4)
> -- access by key name
> my_matrix.m11 = 11
> my_matrix.m12 = 12
> my_matrix.m21 = 21
> my_matrix.m22 = 22
>
> -- or by array index
> my_matrix[1] = 11
> my_matrix[2] = 12
> my_matrix[3] = 21
> my_matrix[4] = 22
>
> But what I would also really like is to be able to access the data
> using a two dimensional array notation, e.g.
>
> my_matrix[2][1] = 21
>
> Is this possible to do? Can somebody explain how I would modify my C
> code (which is based on PiL) to do this?

It is possible. In my_matrix[2][1] there are two metamethod calls. One
on the matrix itself, and one on an intermediate object. To have this
work, you need to make sure the __index of your matrix class returns
an intermediate userdata, a vector. Then in that vector type you have
to implement the __index and __newindex metamethods. To have this
modify the original matrix, the vector object has to be a pointer to
the original matrix rather than a copy of the row/column you indexed.

> And can this peacefully coexist with what I already have, in
> particular, the array index style? So can I have
> my_matrix[1][2]
> and
> my_matrix[2]
> both work?

You cannot have both work, because my_matrix[2] has to return a vector
object for you to be able to modify it with a second indexing.

If performance is not an issue, remember that you can pass any value
when indexing, including tables. So if you make your matrix
metamethods accept tables, you can get the following syntax:

my_matrix[{1, 2}] = 42
assert( my_matrix[{1, 2}] == 42 )

By the way, now that I think about it, it could be nice to have a
syntactic sugar that would transform [x, y] into [{x, y}].