lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Sep 10, 2014 at 9:58 AM, Robert McLay <mclay@tacc.utexas.edu> wrote:
> The question I'm asking is why a string literal can be used with string
> member function like format and rep:
>
>   s = ('5'):rep(10)   --> 5555555555
>
> I would have normally done:
>
>     ss = 5
>     s   = ss:rep(10)
>
> I am unable to find this trick discussed in the "Programming in Lua" books
> or the Lua reference manual.  It clearly works on lua 5.1, 5.2 and luajit
> 2.0.2.  But is this something that I can assume that it will continue to
> work?   Is this trick somehow buried in the manuals and I just missed it?
>
> I found this in some microlight code so I am presuming that it is save to
> use, but I'd like to know.
>
> Thanks for any light on this subject.
> R.
>

Since '5' is a string, you can use any methods from the string table
directly on it. It's less confusing if you choose a different string:

str = "hello"
print(str:rep(3)) --> prints: hellohellohello

print( ("hello"):rep(3) ) --> also prints: hellohellohello

It's the same as calling:
print( string.rep("hello", 3) )

This works because all strings have a metatable like:
metatable = {__index = string}

You can retrieve and modify this metatable using debug.getmetatable()
and debug.setmetatable(), but note that all strings share a single
metatable.

This won't work:
n = 5 --5 is a number, not a string.
print(n:rep(3)) --> error: attempt to index a number value

Since n contains a number, it won't look in the string table. Instead,
it would look in the number metatable - but numbers don't have a
metatable by default, so instead it throws an error.

Again, you can set a metatable for numbers (shared among all numbers)
using the debug library, and then the above example can work:
debug.setmetatable(42, debug.getmetatable("")) --copy string metatable
to numbers.
--it doesn't matter which number or which string we use.
n = 5
print(n:rep(3)) --> prints: 555

Now numbers have a metatable where __index = string, so it looks up
string.rep(). It's not recommended to do this in practice, but it can
be done.

HOWEVER, a lot of Lua functions will convert numbers to strings
automatically, so this WILL work without any metatable magic:
n = 5
print(string.rep(n, 3)) --> prints: 555

This works because we don't try to look inside n; we get string.rep
directly and call it, and it converts n to a string on its own.

-- 
Sent from my Game Boy.