Parki
Parki

Reputation: 159

Weird behavior of syntax sugar(colon) in Lua

function string.test(s)
    print('test')
end

a = 'bar'
string.test(a)
a:test()

All is fine until next example.

function table.test(s)
    print('test')
end

b = {1,2,3}
table.test(b)
b:test() -- error

Why do I getting the error?
It was working fine at strings.

Upvotes: 1

Views: 1022

Answers (2)

warspyking
warspyking

Reputation: 3113

While daurn answers your question nicely, allow be to explain why this is.

In Lua, all datatypes can have a metatable. (Although it's quite different when dealing with numbers,bools,etc. See debug.setmetatable.) This includes the string. By default this is set to index string library with __index, it is when make syntactic sugar like print(s:sub(1,5)) (s being a string) possible.

This is NOT the same with tables. By default tables have NO metatable. You have to manually set it with setmetatable.

And to conclude my answer, enjoy this code snippet

debug.setmetatable(0,{__index=math})
debug.setmetatable(function()end,{__index=coroutine})
debug.setmetatable(coroutine.create(function()end), {__index=coroutine})
local function Tab(tab)
    return setmetatable(tab,{__index=table})
end

This basically allows you to use math functions on numbers

local x = 5.7
print(x:floor())

And do similar things with functions and threads, using coroutine functions:

print:create():resume()

Pretty hacky if you ask me

And of course, create tables and use table functions on them:

local x = Tab{1,2,3,4}
x:insert(5)
x:remove(1)
print(x:concat(", "))

I find it hard to imagine anybody who don't like cool tricks like that.

Upvotes: 2

daurnimator
daurnimator

Reputation: 4311

Tables do not have a metatable by default like strings do.

Try instead:

function table.test(s)
    print('test')
end

b = setmetatable({1,2,3}, {__index=table})
table.test(b)
b:test() -- error

Upvotes: 5

Related Questions