stringluaioluajit

Add method to string and modify self in Lua


How can I add a method to the string table and modify self inside it ?

Basically, I'm trying to mimic the behaviour of the io.StringIO.read method in python, which reads n char in the string and returns them, modifying the string by "consuming" it.

I tried this:

function string.read(str, n)
  to_return = str:sub(1, n)
  str = str:sub(n + 1)
  return to_return
end

local foo = "heyfoobarhello"
print(string.read(foo, 3))
print(foo)

Output is:

hey
heyfoobarhello

I expected the second line to be only foobarhello.

How can I achieve this ?


Solution

  • To mimic Python's io.StringIO class, you must make an object that stores both the underlying string and the current position within that string. Reading from an IO stream normally does not modify the underlying data.

    local StringIO_mt = {
      read = function(self, n)
        n = n or #self.buffer - self.position + 1
        local result = self.buffer:sub(self.position, self.position + n - 1)
        self.position = self.position + n
        return result
      end,
    }
    StringIO_mt.__index = StringIO_mt
    
    local function StringIO(buffer)
      local o = {buffer = buffer, position = 1}
      setmetatable(o, StringIO_mt)
      return o
    end
    
    local foo = StringIO"heyfoobarhello"
    print(foo:read(3))
    print(foo:read())
    

    Output:

    hey
    foobarhello
    

    I don't recommend adding this class or method to Lua's string library, because the object has to be more complex than just a string.