Reputation: 527
With methods like io.close(), you can use it like this:
file:close()
Is there a way to create a custom function that works like that, where you can call it on a variable?
For me I am trying to use it to separate arguments from a text file by using string.find to find spaces
So in the text file it looks like
this is some input
And the readArgs() function should return the entire line in a table with args[1] = "So", args[2] = "in", args[3] = "the" etc. after being called on the line
function readFile(file)
local lines = {}
assert(io.open(file), "Invalid or missing file")
local f = io.open(file)
for line in f:lines() do
lines[#lines+1] = line
end
return lines
end
function readArgs(line) -- This is the function. Preferably call it on the string line
--Some code here
end
Upvotes: 3
Views: 724
Reputation: 20838
Based on your description it sounds like you're after something similar to this syntax:
local lines = readFile(file)
lines:readArgs(1) -- parse first line {"this", "is", "some", "input"}
Metatables can help with this:
local mt = { __index = {} }
function mt.__index.readArgs(self, linenum)
if not self[linenum] then return nil end
local args = {}
for each in self[linenum]:gmatch "[^ ]+" do
table.insert(args, each)
end
return args
end
You'll have to do a slight change in your readFile
and attach that metatable to the lines
you're returning:
function readFile(file)
-- ...
return setmetatable(lines, mt)
end
Edit: To answer the OP's comment, a call like this:
lines:readArgs(1)
is just syntactic sugar for:
lines.readArgs(lines, 1)
When the lua VM executes the above line the following happens:
lines
have a readArgs
key?lines
have a metatable.__index? In this case it does, so the function assigned to __index.readArgs
is used.readArgs
is now called with the parameters above: self
= lines, linenum
= 1There is nothing special about self
here, it's just a regular parameter; you can name it anything you want really.
Upvotes: 3