DeGariless 0 Posted August 21, 2016 Share Posted August 21, 2016 I'll use short example programs to explain exactly what I am trying to achieve. I have a a file test.lua that looks like this testAPI = require("testAPI") testAPI.talk() testAPI.setWord("Goodbye") testAPI.talk() I also have a file /lib/testAPI.lua that looks like this testAPI = {} local word = "Hello" function testAPI.talk() print(word) end function testAPI.setWord(s) word = s end return testAPI when I run test.lua for the first time I get the output Hello Goodbye but than I run it a second time and I get Goodbye Goodbye How can I get the variable 'word' to reset anytime a new program uses that API? Quote Link to post Share on other sites
0 Fingercomp 37 Posted August 21, 2016 Share Posted August 21, 2016 (edited) This happens because package library caches return values of libraries. This is simply workarounded, though. local lib = {} -- the following line is important lib.__index = lib -- the "word" variable will be defined later, so it will not be cached -- define your functions (note: colons should be used) function lib:talk() -- use "self" to access fields of library table print(self.word) end function lib:setWord(s) -- and here, too self.word = s end function lib:setWordAndTalk(s) -- if you need to access *methods* (functions) of your library, you should use the colon! self:setWord(s) self:talk() end return function() local object = { -- declare your variables here if you want them to be created with each new instance word = "Hello" } setmetatable(object, lib) return object end As I already said, the return value is cached. If you just return the table, it gets cached, and the result will be the same (a single library table for all programs that require'd the library.In the code above, though, the thing that's cached is a function. It's sole purpose is to create a new instance of library. It defines some variables that won't be cached, and sets the library table as a metatable for the object. Then it just returns the object.The library should be used differently than a regular one: local lib = require("lib")() -- get the function, and call it -- use colon to access methods of library... lib:talk() lib:setWord("Test") -- and dot to access properties (regular variables) of library: print(lib.word) lib:setWordAndTalk("Hello, world!") Speaking of tables, they are not copied when passed as an argument to a function. Here's the code that demostrates this: local function setValue(tbl, value) tbl.test = value end local someTable = {test="Hello"} print(someTable.test) setValue(someTable, "Hi") print(someTable.test) The output: Hello Hi As you can see, the function didn't get a copy of table, instead, it modified a field of the same table! In the C (C++) programming language, this is called a reference to the value, and it's used to avoid creating a copy of big objects.Moreover, this is a key concept of Lua's object-oriented programming: all methods of some class, when called, get a reference to the class which they can use. That's why methods should be generally called like this: class:method(args). This implicitly passes the class variable as the first argument for the method. Edited August 22, 2016 by Fingercomp Quote Link to post Share on other sites
I'll use short example programs to explain exactly what I am trying to achieve.
I have a a file test.lua that looks like this
I also have a file /lib/testAPI.lua that looks like this
when I run test.lua for the first time I get the output
Hello
Goodbye
but than I run it a second time and I get
Goodbye
Goodbye
How can I get the variable 'word' to reset anytime a new program uses that API?
Link to post
Share on other sites