I'm wondering if anyone can explain why this is
It's a "security" thing, involving scripts (from freemodels or friends) interfering with each other.
All strings share the same metatable. This would be true even for separate scripts on the same client / on the server. That means if I did something like
-- Evil script: local meta = getmetatable("cat") meta.__index = function() return error; end -- By default, `meta.__index` would be the `string` library, -- which is how you can do `:sub` and the like. ----------- -- Other Script, minding it's own business: local message = "Hello" for i = 1, 5 do print( message:sub(1, i) ) end
The second script could get an error, because the first one invisibly changed the way strings behave.
In general you could be much more malicious with well designed metatable modifications. So ROBLOX doesn't allow this.
Locking the metatable is an easier (and much more reasonable) solution that modifying the core of Lua's code in order to make it generate new metatables for each thread, especially since Lua essentially allows that to be done very easily.
EDIT: A related thing: This is the same reason that the math
, string
, table
, etc libraries are locked. It's also the same reason _G
is no longer the default environment --
print( _G.print == print )
and you'll get true
. In standard Lua,
_G.cat = 1; print(cat); -- 1
print
, pcall
, string
, etc all come from _G
in standard Lua, implicitly (i.e., _G
is the global environment).
ROBLOX's solution to that problem is to make _G
not the default environment, which again, Lua makes relatively easy, and doesn't require modifying the way Lua works.