Reputation: 774
While learning Lua, I borrowed some code from here to use string indexing, which is exactly this:
getmetatable("").__index = function(str, i) return string.sub(str, i, i) end
After that, I wrote a function to reverse a string as practice.
function reverse_string(str)
local s = ""
for i = string.len(str), 1, -1 do s = s .. str[i] end
return s
end
That works fine, until I change the string.len(str)
to str:len()
, then I get this error:
reverse.lua:9: bad argument #2 to 'sub' (number expected, got string)
Debugging print()'s tell me that the __index
function is being called on str:len()
, and that the i
argument is becoming the string "len". I know that str:len() works without the metatable there, but as soon as I add it this happens, why?
Upvotes: 3
Views: 785
Reputation: 757
The index function is passed the table, and the key that is being indexed. so 'str' should be the string and 'i' should be key in your case. Because "len" is not in the meta table it calls __index and passes the string as the first argument and the key ("len") as the second argument. it looks as though you need to check to the type of 'i' to see what to do for better handling of strings
getmetatable("").__index = function(str, key)
if type(key) == "string" then
return string[key]
else
return string.sub(str, key, key)
end
end
str = "hello, world!"
print(str:len())
print(str[5])
see here for more info
Upvotes: 2
Reputation: 122373
From Lua 5.2 Refernce Manual:String Manipulation
The string library provides all its functions inside the table string. It also sets a metatable for strings where the __index field points to the string table. Therefore, you can use the string functions in object-oriented style. For instance, string.byte(s,i) can be written as s:byte(i).
So, the object oriented style like str:len()
comes from the default metamethod __index
, which you have modified.
Upvotes: 3