13

I came across tables that have square brackets around keys:

local commands_json =
{
    ["request"] = {
        ["application"] = PW_APPLICATION,
        ["push_token"] = deviceToken
    }
}

Can the square brackets be omitted?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
hamobi
  • 7,940
  • 4
  • 35
  • 64
  • Perhaps the documentation says it best: [Each field of the form `[exp1] = exp2` adds to the new table an entry with key `exp1` and value `exp2`....](http://www.lua.org/manual/5.3/manual.html#3.4.9). In other words, the key value is determined at run-time. – Tom Blodget Jan 09 '16 at 00:28

2 Answers2

19

It's simply the long form of specifying keys in a table. You can put any value between the [] (except nil. And floating-point NaNs). Whereas without them, you can only use identifiers.

For example:

tbl =
{
  key name = 5,
}

That's a compile error, since "key name" isn't an identifier (due to the space). This works:

tbl =
{
  ["key name"] = 5,
}

And this:

tbl =
{
  "key name" = 5,
}

Is also a compile error. If Lua sees a naked value like this, it thinks you're trying to add to the array part of the table. That is, it confuses it with:

tbl =
{
  "key name",
}

Which creates a 1-element array, with tbl[1] equal to "key name". By using [], the compiler can easily tell that you meant for something to be a key rather than the value of an array element.

The long form also lets you distinguish between:

local name = "a name";

tbl =
{
  ["name"] = 5,
  [name] = 7,
}

The second part means to evaluate the expression name, the result of which will be the key. So this table has the keys "name" and "a name".

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • if you have a table with an odd key like ["key name"] ... then at that point youd no longer be able to retrieve the value using dot notation? you'd have to go table["key name"] ?? – hamobi Jan 08 '16 at 23:09
  • Yes, that's correct. However, that's not an "odd key". For tables that are intended to mimic structs, `.` notation is important for ease-of-use. For tables that are more like associative data arrays, notation is irrelevant. – Nicol Bolas Jan 08 '16 at 23:11
  • Just a nitpick, but nil isn't the only unusable index. – warspyking Jan 10 '16 at 02:20
  • @warspyking: Well, Lua 5.1 only excepts `nil`; 5.2+ adds floating-point NaN to that list, for obvious reasons. – Nicol Bolas Jan 10 '16 at 03:12
  • @Nicol I think it's worth mentioning NaN. And I can't seem to use NaN in 5.1 either :P – warspyking Jan 10 '16 at 05:48
2

You cannot omit the brackets

> x = { 'a' = 1 }
stdin:1: '}' expected near '='

the correct code is

> x = { ['a'] = 1 }
> print(x['a'])
1

or

> x = { a = 1 }
> print(x['a'])
1

However, the second one has its limitations. What if you want to have a key called "-"?

> x = { - = 1 }
stdin:1: unexpected symbol near '='
> x = { '-' = 1 }
stdin:1: '}' expected near '='

again the correct way is to use brackets

> x = { ['-'] = 1 }
> print(x['-'])
1

Or you want to create a field of name which is contained in a variable called a?

> a = 'cat'
> x = { [a] = 1 } 
> print(x['cat'])
1

Brackets are used as a general form of key creation, they give you ability to put any hashable object as a key - not only strings.

lejlot
  • 64,777
  • 8
  • 131
  • 164