> so you may want to leave the __metatable=false out all together.

I don't think that's a good idea. Without that you could pass the table to a function that modifies the metatable and inadvertently remove the readonly protection.

> Another comment while reading the code again; I think the call to error() should use the PL error methods

I don't understand what you mean. tablex.lua on line 38 uses error. It wraps it in a function (complain()) to format the message in a specific manner. However, complain() doesn't format the message in an intelligible way for this case.  Basically, if there is another error function tablex isn't using it so either that's an oversight in tablex which should be itself changed or there is a reason it's not used. If it's not used for a specific reason then readonly() shouldn't be using it either.