NicoAdrian
NicoAdrian

Reputation: 1034

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 ?

Upvotes: 1

Views: 1219

Answers (2)

koyaanisqatsi
koyaanisqatsi

Reputation: 2793

You can add methods to the datatype string independently from the string table.
Short example that shows that the string methods even work if string table gets deleted...

string=nil

return _VERSION:upper():sub(1,3)
-- Returning: LUA

So you can add a method...

-- read.lua
local read = function(self, n1, n2)
return  self:sub(n1, n2)
end

getmetatable(_VERSION).__index.read=read

return read

...for all strings.
( Not only _VERSION )

And use it...

do require('read') print(_VERSION:read(1,3):upper()) end
-- Print out: LUA

Upvotes: 3

luther
luther

Reputation: 5544

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.

Upvotes: 3

Related Questions