Search code examples
luatorch

How does Lua's print work and what is the difference between `__tostring` and `__tostring__` in Lua/Torch


I've noticed that there is a __tostring__ sometimes used in Torch. In my torch-dataframe project I have a __tostring that handles print(my_data). It works exactly like expected in raw Torch but when I run iTorch it also prints the raw underlying data-table as if it printed a separate return statement.

After looking into the documentation I've found that Torch often uses __tostring__ and I'm therefore curious of what the difference is? It would also be interesting to get a better understanding of the print call in Lua, coming from R all classes are able to define their own print.class that neatly takes care of the output and there are no side effects such as the one I see in the iTorch case above.


Solution

  • By default what happens is as follow:

    [...] print always calls tostring to format its output.) However, when formatting an object, tostring first checks whether the object has a metatable with a __tostring field. If this is the case, tostring calls the corresponding value (which must be a function) to do its job, passing the object as an argument. Whatever this metamethod returns is the result of tostring

    From PiL, 13.3.

    Example:

    > t = setmetatable({}, {__tostring = function(x) return "foo" end})
    > print(t)
    foo
    

    When you use the Torch class system an appropriate metatable is created. When __tostring is called this metatable will look for __tostring__, and if found, the corresponding function will be used (for more details see: these parts).

    Example:

     > do local Foo = torch.class("Foo"); function Foo:__tostring__() return "this is foo" end end
     > f = Foo(); print(f)
     this is foo
    

    So if you implement a custom Torch class you are only supposed to override __tostring__ since Torch takes care of the rest.

    UPDATE

    Why iTorch adds the additional print statement to its output?

    iTorch requires torch/env which replaces the default print function. This is what explains the outputs you get.