Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call string method on string literal

Tags:

lua

If I have a variable of string type, I can use the : syntax to call functions on the string metatable:

local s = "%d"
print(s:format(s:byte(1)))  -- 37

But this doesn't work for string literals:

print("%d":format("%d":byte(1)))
-- ')' expected near ':'

Why? Is there a trick to make this work?

like image 947
Artyer Avatar asked Jul 16 '26 23:07

Artyer


2 Answers

From section 9 of the manual (sic):

9 – The Complete Syntax of Lua

[...]

var ::=  Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name

[...]

prefixexp ::= var | functioncall | ‘(’ exp ‘)’
functioncall ::=  prefixexp args | prefixexp ‘:’ Name args

[...]

Basically:

  • A "method" functioncall is made of four parts: prefixexp, the colon, the name of the method, and its arguments.
  • A prefixexp can be either a functioncall itself, an exp wrapped inside a pair of parentheses, or a var.
  • A var can be an identifier, or its indexed/dotted counterpart.

This effectively disallows using the shorthand :method syntax on all kinds of literal expressions, not just strings. That said, these are all invalid syntax:

nil:has_no_methods()
true:or_false()
2:too()
[[long strings]]:same_thing()
function() end:really('?')
{}:h_yes_definitely('!')

...but this is valid:

foo:bar 'baz':qux()  -- Parsed as foo:bar('baz'):qux()

In conclusion, either use a variable, or just wrap your literal value in parentheses.

like image 104
InSync Avatar answered Jul 20 '26 18:07

InSync


Surround the literal with parentheses:

print(("%d"):format(("%d"):byte(1)))
like image 24
Alexander Mashin Avatar answered Jul 20 '26 20:07

Alexander Mashin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!