This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Lignum's profile picture

Lua interpreter doesn't respect __tostring

Started by Lignum, 06 September 2015 - 09:15 PM
Lignum #1
Posted 06 September 2015 - 11:15 PM
As you know, the Lua interpreter automatically outputs the result of the entered expression. If the result is a table, this table will be serialised for convenience. However, it completely ignores the __tostring metamethod when doing this.

To elaborate, this is what currently happens:

lua> setmetatable({}, { __tostring = function() return "Hello!" end })
{}

What should instead happen is this:

lua> setmetatable({}, { __tostring = function() return "Hello!" end })
Hello!

While you can achieve the desired behaviour by wrapping the expression in a tostring call, I think it should behave this way by default even though it's a minor detail.
Wojbie #2
Posted 06 September 2015 - 11:23 PM
Serialization is supposed to store contents of table into string so it can be then recreated from said string. If it used __tostring then the table would not be unserializable after the serialization.

What i guess you are suggesting is that lua interpreter attempt to use __tostrting befre outputting serialized version?
Lignum #3
Posted 06 September 2015 - 11:26 PM
What i guess you are suggesting is that lua interpreter attempt to use __tostrting befre outputting serialized version?

Yes, that is what I mean.
flaghacker #4
Posted 07 September 2015 - 09:45 PM
Your code sets the metatable for one table, and then tries to serialise another. Try this instead:


local t = {}
setmetatable (t, {__tostring = function () return "test" end})
print (t)

Edit: now I'm confused. Are you only running that one line of code? That shouldn't print anything… Does my code work?
Edited on 07 September 2015 - 07:57 PM
HPWebcamAble #5
Posted 07 September 2015 - 09:50 PM
Your code sets the metatable for one table, and then tries to serialise another. Try this instead:

Doesn't 'setmetatable' return the table? (It also changes the table itself, obviously, so any reference to it will be the same as the one it returns)
And the Lua interpreter tries to serialize any tables that gets returned, correct?

Also, you missed a ')' on the second line
Edited on 07 September 2015 - 07:50 PM
flaghacker #6
Posted 07 September 2015 - 09:59 PM
That could be the case, I'm not sure. Could you try to explicitly use "print" to see if the problem is really the lua program?

Fixed the ')', thanks.
KingofGamesYami #7
Posted 07 September 2015 - 10:29 PM
The lua program doesn't call tostring on the table - it serializes it. Put a function in the table, and, since it can't be serialized, it'll tostring it.

Lines 60 - 67 of 'rom/programs/lua'

if type( value ) == "table" then
  local ok, serialized = pcall( textutils.serialize, value )
  if ok then
    print( serialized )
  else
    print( tostring( value ) )
  end
end

Example of what I mean:


lua> setmetatable( { function() end }, {__tostring = function() return "Hello!" end } )
Hello!
Edited on 07 September 2015 - 08:35 PM
Lignum #8
Posted 08 September 2015 - 01:57 AM
Put a function in the table, and, since it can't be serialized, it'll tostring it.

Indeed it does! Thanks for the workaround, though the downside is that you can't serialise the table manually with this method.
dan200 #9
Posted 11 December 2015 - 03:21 PM
fixed for 1.76pr3