Jump to content




Lua interpreter doesn't respect __tostring


  • This topic is locked This topic is locked
8 replies to this topic

#1 Lignum

  • Members
  • 558 posts

Posted 06 September 2015 - 10: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.

#2 Wojbie

  • Members
  • 631 posts
  • LocationKinda lost

Posted 06 September 2015 - 10: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?

#3 Lignum

  • Members
  • 558 posts

Posted 06 September 2015 - 10:26 PM

View Postwojbie, on 06 September 2015 - 10:23 PM, said:

What i guess you are suggesting is that lua interpreter attempt to use __tostrting befre outputting serialized version?

Yes, that is what I mean.

#4 flaghacker

  • Members
  • 655 posts

Posted 07 September 2015 - 08: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 by flaghacker, 07 September 2015 - 08:57 PM.


#5 HPWebcamAble

  • Members
  • 933 posts
  • LocationWeb Development

Posted 07 September 2015 - 08:50 PM

View Postflaghacker, on 07 September 2015 - 08:45 PM, said:

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 by HPWebcamAble, 07 September 2015 - 08:50 PM.


#6 flaghacker

  • Members
  • 655 posts

Posted 07 September 2015 - 08: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.

#7 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 07 September 2015 - 09: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 by KingofGamesYami, 07 September 2015 - 09:35 PM.


#8 Lignum

  • Members
  • 558 posts

Posted 08 September 2015 - 12:57 AM

View PostKingofGamesYami, on 07 September 2015 - 09:29 PM, said:

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.

#9 dan200

  • Administrators
  • 542 posts
  • LocationCambridge, England

Posted 11 December 2015 - 03:21 PM

fixed for 1.76pr3





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users