gwizardry
gwizardry

Reputation: 511

Basic Example of Lua Table Attribute Misunderstanding

I'm trying to create some simple variables which can be used to compare the current direction of a sprite in a game and obtain the opposite and adjacent directions. Such that if the player's direction is set to U by direction=U then I can access direction.opposite to get D

This example clearly shows i havent understood Lua 101 but I'm intrigued if and how I can get the functionality I want. Sure, I can replace the values with strings and compare to names but is there a way to preserve my intended functionality without resorting to string comparisons (or even comparing numbers in their place) which i suppose suffer in performance compared to checking just the table address.

U, D, R, L  = {},{},{},{}
U           = {opposite = D, adjacent = {R,L},name = 'up'}
D           = {opposite = U, adjacent = {R,L},name = 'down'}
R           = {opposite = L, adjacent = {U,D},name = 'right'}
L           = {opposite = R, adjacent = {U,D},name = 'left'}

print(U.opposite.name)

Here print prints 'nil' when i'd like it to print 'down'

Upvotes: 2

Views: 90

Answers (2)

lhf
lhf

Reputation: 72312

As explained by LMD, you're replacing the tables created in the first line.

Here is an alternative that looks like your original code:

local function bind(t,b)
        for k,v in pairs(b) do t[k]=v end
end

U, D, R, L  = {},{},{},{}

bind(U, {opposite = D, adjacent = {R,L}, name = 'up'})
bind(D, {opposite = U, adjacent = {R,L}, name = 'down'})
bind(R, {opposite = L, adjacent = {U,D}, name = 'right'})
bind(L, {opposite = R, adjacent = {U,D}, name = 'left'})

print(U.opposite.name)

Upvotes: 1

Luatic
Luatic

Reputation: 11171

This example clearly shows i havent understood Lua 101 but I'm intrigued if and how I can get the functionality I want.

It is possible to fix your code simply by not replacing the tables with new tables, but rather assigning to them (this is in fact the only possible way to create circular table reference structures in Lua; using only table constructors it won't work):

U, D, R, L  = {name = "up"},{name = "down"},{name = "right"},{name = "left"}

U.opposite = D; U.adjacent = {R,L}
D.opposite = U; D.adjacent = {R,L}
R.opposite = L; R.adjacent = {U,D}
L.opposite = R; L.adjacent = {U,D}

print(U.opposite.name)

prints down as expected.

Sure, I can replace the values with strings and compare to names but is there a way to preserve my intended functionality without resorting to string comparisons (or even comparing numbers in their place) which i suppose suffer a performance compared to checking just the table address.

I don't get what you mean by this. All strings in Lua are interned, making string comparisons reference comparisons that run in constant time. Number comparisons are obviously constant time as well. And table comparisons simply compare the references. So all three should take roughly the same constant time.

Upvotes: 4

Related Questions