Search code examples
lua

Call string method on string literal


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?


Solution

  • 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.