This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Thegameboy's profile picture

Variable passing between two separate files

Started by Thegameboy, 16 February 2015 - 10:49 PM
Thegameboy #1
Posted 16 February 2015 - 11:49 PM
For modding purposes, I want there to be a variable exchange between two different Lua files; apparently os.run and shell.run can't return variables to the original code that called it.

Basically, something like this:

Mod file:


local mod = {
  name = "test",
  --moreModStuffHere
}


return mod

Base code:

local mod = shell.run("modFile")

print(mod.name)

It may be simple and I'm just missing something, but any ideas on how to get this to work?
Bomb Bloke #2
Posted 16 February 2015 - 11:56 PM
In a nutshell, what you're trying to do is have a script load in information from a file.

In this particular case, the answer would be to manually read the file data and use textutils.unserialize() on it. Eg:

Mod file:
{
  name = "test",
  --moreModStuffHere
}

Base code:
local myFile = fs.open("modFile")
local mod = textutils.unserialize(myFile.readAll())
myFile.close()

print(mod.name)

If you actually wanted executable code in your "mod" file, you'd rig it up as an API.
InDieTasten #3
Posted 17 February 2015 - 12:32 AM
I guess the part that really gets him is the return of values. Unfortunately lua chunks can not return values as if they were functions. You would have to write an interface which executes an "anonymous" function within the mod files. So that every mod has to have a certain function, for example run(), which gets loaded and executed by the host application(your base code).

Without testing Lignums code, I'll take his word for it. I know that loading a file or string will return the chunk as a function, which is able to take parameters, but of some source I was thinking the return value of the chunks function was allocated to handle debugging stuff, since the chunks themselve have a copy of the original source to for example, tell you which line the runtime error occured. I guess lua handles this somewhat deeper in the codez than I thought. So much for that misconception ^_^/>
Edited on 16 February 2015 - 11:51 PM
Lignum #4
Posted 17 February 2015 - 12:41 AM
Unfortunately lua chunks can not return values as if they were functions.

Yes, they can. Lua chunks are functions. Try this:
Mod file:

return 5

Base code:

local modFunc = loadfile("modfile")
print(type(modFunc)) --# We've loaded the mod file as a function.

local theNumber = modFunc()
print(theNumber) --# Prints 5.
Bomb Bloke #5
Posted 17 February 2015 - 12:41 AM
Again, that is the circumstance in which you would build an API. For the specific purpose asked about, however, textutils.unserialize() is sufficient.
Thegameboy #6
Posted 20 February 2015 - 08:54 PM
Hi.


I'd previously posted here about trying to run a Lua script that would pass variables onto the script that started it. For example…


local _, returnedVariables = shell.run("mod")

I understand that returning variables is not a functionality of shell.run; I was merely using it as an example. Bomb Bloke had suggested that I use textutils.unserialize to manually read the mod file and convert it into a table, and if necessary, load it as an API to execute code. However, this really doesn't work. I've looked into it and textutils.unserialize does not support functions within the table, and os.loadAPI doesn't allow any kind of return values either.

In regards to my previous post, I believe I should have been a bit more specific and detailed:

Mod file:


--init code up here
mod = {
  name = "testMod",
  --more arbitrary properties here

  mouse_click = function()
	print("test!")
  end,
  timer = function(event)
	if event[2] == "timer" then
	  print("another test!")
	end
  end
}

return mod

Basically, the modding is event based. Any event that has a function attached to it will execute in the game code once that event is triggered. My only problem here is that nothing I've tried can return variables to the script that started it like a function. I've considered using environments somehow and came up with the idea of putting it in _G for the game to retrieve. Although I'm sure there's a better way to do it - any suggestions?
InDieTasten #7
Posted 20 February 2015 - 08:57 PM
Lignum posted some example code that fits your question ;)/>
SquidDev #8
Posted 20 February 2015 - 09:00 PM
Can you not do:


local mod = loadfile("mod")

print("Loaded " .. mod.name)

Edit: Woops, only just saw Lignum's post. Sorry.
Edited on 20 February 2015 - 08:00 PM
Bomb Bloke #9
Posted 20 February 2015 - 11:09 PM
Mod file:
--init code up here

name = "testMod",
--more arbitrary properties here

function mouse_click()
	print("test!")
end

function timer(event)
	if event[2] == "timer" then
		print("another test!")
	end
end

Base code:
os.loadAPI("mod")

print(mod.name)
mod.mouse_click()
mod.timer({os.pullEvent()})

os.unloadAPI("mod")