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

Calling a function by using a string of its name, and on a remote computer via rednet too

Started by Yarillo, 30 October 2015 - 12:38 AM
Yarillo #1
Posted 30 October 2015 - 01:38 AM
Hi. I don't know if it's a well known trick so I decided to show you guys that.

What does it add ?

Sorry. I made a table because it seemed like a good idea but it's not enabled on the forum… so I had to improvise with my now useless html code.



How do I install it:

- pastebin get wAwjUyj3 remoteAPI
Then put this above your code:
os.loadAPI("remoteAPI")

Or:

- Simply copy/paste it above your code

Or:

- pastebin get wAwjUyj3 remoteAPI
Then put this above your code:
shell.run("remoteAPI")

The code:

The trick is the getfenv() function.



function split(str,splitter)
	if not splitter then return end
	if not str then return end
	words = {}
	i=0
	for part in string.gmatch(str, "[^%"..splitter.."]+") do -- get each part
		i=i+1
		words[i] = part
	end
	return words
end
string.split = split

function call(func, ...)
	args = {...}
	
	if type(func) == "string" then
		func = getfenv(1)[func]
	end
	
	if type(func) == "function" then
		return func(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10])
	else
		error("Non-existant function")
	end
end

function remoteInterpret(message)
	args = string.split(message, ",")
	func = getfenv(1)[args[1]] -- getfenv(1) contains all non-local variables (so functions too) so getfenv(1)["test"] returns a function named test, if there's one.
	-- the input looks like that:
	-- functionName,param1,param2...
	-- getfenv(1)[args[1]] returns the function named after the first arg of the function
	return func(args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11])
end

function remoteCall(ID, func, ...)
	if type(ID) ~= "number" then
		error("expected an ID (number) as a first argument")
	end
	if type(func) ~= "string" then
		error("expected a function name (string) as a second argument")
	end
	args = {...}
	rednet.send(ID, func..","..table.concat(args, ","))
end

Edited on 30 October 2015 - 12:50 AM
Anavrins #2
Posted 30 October 2015 - 04:01 AM
At line 22, you don't need to do args[1], args[2], args[3], etc…
Doing func(…) will work just as well, and for more than 10 args even.
Edited on 30 October 2015 - 03:02 AM
Bomb Bloke #3
Posted 30 October 2015 - 04:14 AM
unpack() is also handy; you could replace this:

return func(args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11])

… with this:

return func(unpack(args, 2))
Creator #4
Posted 30 October 2015 - 05:17 AM
Or even
return func()
Bomb Bloke #5
Posted 30 October 2015 - 09:04 AM
You're thinking of the line Anavrins referred to, methinks.
Creator #6
Posted 30 October 2015 - 09:22 AM
Yep, right you are.