Ian Boyd
Ian Boyd

Reputation: 256999

How to reference lua table member from table member?

i have a table in lua:

enUS = {
   LOCALE_STHOUSANDS = ",",  --Thousands separator e.g. comma

   patNumber = "%d+["..LOCALE_STHOUSANDS.."%d]*", --regex to find a number

   ["PreScanPatterns"] = {
      ["^("..patNumber..") Armor$"] = "ARMOR",
   }
}

So you see there is a whole chain of self-references in this table:

How can i perform self-referencing in an lua table?


What i don't want to do is have to hard-replace the values; there are hundreds of references:

enUS = {
   LOCALE_STHOUSANDS = ",",  --Thousands separator e.g. comma

   patNumber = "%d+[,%d]*", --regex to find a number

   ["PreScanPatterns"] = {
      ["^(%d+[,%d]*) Armor$"] = "ARMOR",
   }
}

Upvotes: 8

Views: 5907

Answers (2)

furq
furq

Reputation: 5808

There's no way of doing this inside the constructor itself, but you can do it after creating the table like so:

enUS = {
   LOCALE_STHOUSANDS = ","
}

enUS.patNumber = "%d+["..enUS.LOCALE_STHOUSANDS.."%d]*"
enUS.PreScanPatterns = {
  ["^("..enUS.patNumber..") Armor$"] = "ARMOR",
}

If you specifically need to refer to the current table, Lua provides a "self" parameter, but it's only accessible in functions.

local t = {
  x = 1,
  y = function(self) return self.x end
} 

-- this is functionally identical to t.y
function t:z() return self.x end

-- these are identical and interchangeable
print(t:y(), t.z(t))
-- 1, 1

Upvotes: 5

Nicol Bolas
Nicol Bolas

Reputation: 474296

How can i perform self-referencing in an lua table?

You don't.

Lua is not C. Until the table is constructed, none of the table entries exist. Because the table itself doesn't exist yet. Therefore, you can't have one entry in a table constructor reference another entry in a table that doesn't exist.

If you want to cut down on repeated typing, then you should use local variables and do/end blocks:

do
  local temp_thousands_separator = ","
  local temp_number_pattern = "%d+["..LOCALE_STHOUSANDS.."%d]*"

  enUS = {
   LOCALE_STHOUSANDS = temp_thousands_separator,  --Thousands separator e.g. comma

   patNumber = "%d+["..temp_thousands_separator.."%d]*", --regex to find a number

   ["PreScanPatterns"] = {
      ["^("..temp_number_pattern..") Armor$"] = "ARMOR",
   }
  }
end

The do/end block is there so that the temporary variables don't exist outside of the table creation code.

Alternatively, you can do the construction in stages:

  enUS = {}
  enUS.LOCALE_STHOUSANDS = ",",  --Thousands separator e.g. comma

  enUS.patNumber = "%d+["..enUS.LOCALE_STHOUSANDS.."%d]*", --regex to find a number

  enUS["PreScanPatterns"] = {
      ["^("..enUS.patNumber..") Armor$"] = "ARMOR",
   }

Upvotes: 10

Related Questions