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

Program Migration

Started by mentalr0b123, 02 November 2015 - 02:59 PM
mentalr0b123 #1
Posted 02 November 2015 - 03:59 PM
MIGRATION

—————————————————

@Author = mentalrob

@Version = 1.1 [[There is never be an update]]

@Description = This program migrates first program to second program and write it an output file

@Migration = If you migrate a program to another program, first program will run inside the second program

How it works


——————————————————–

migration <firstprogram> <secondprogram> <outputfile>

Actually This program reads your firstprogram sourcecode and adds the "function progf()" string to the beginning of the sourcecode

It does this function again for secondprogram

And then Program adds sourcecodes

Then adds "parallel.waitForAll()" method end of the sourcecodes

and writing it an output file


pastebin get xWSWHfPM migration
migrate <firstprogram> <secondprogram> <output>
Edited on 02 November 2015 - 05:37 PM
Creator #2
Posted 02 November 2015 - 04:47 PM
Very nice! However, I don't quite get why I would need that. Can you give an example?
mentalr0b123 #3
Posted 02 November 2015 - 05:13 PM
Here is a test program:

rednet.open("left")
while true do
  id ,msg = rednet.receive()
  if msg == "shutdown" then
	os.shutdown()
  end
end
And here is the shell program in /rom/programs (NOTE : tArgs{…} deleted)

local multishell = multishell
local parentShell = shell
local parentTerm = term.current()
if multishell then
	multishell.setTitle( multishell.getCurrent(), "shell" )
end
local bExit = false
local sDir = (parentShell and parentShell.dir()) or ""
local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
local tAliases = (parentShell and parentShell.aliases()) or {}
local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
local tProgramStack = {}
local shell = {}
local tEnv = {
[ "shell" ] = shell,
[ "multishell" ] = multishell,
}
-- Colours
local promptColour, textColour, bgColour
if term.isColour() then
promptColour = colours.yellow
textColour = colours.white
bgColour = colours.black
else
promptColour = colours.white
textColour = colours.white
bgColour = colours.black
end
local function run( _sCommand, ... )
local sPath = shell.resolveProgram( _sCommand )
if sPath ~= nil then
  tProgramStack[#tProgramStack + 1] = sPath
  if multishell then
	  multishell.setTitle( multishell.getCurrent(), fs.getName( sPath ) )
  end
	 local result = os.run( tEnv, sPath, ... )
  tProgramStack[#tProgramStack] = nil
  if multishell then
	  if #tProgramStack > 0 then
		  multishell.setTitle( multishell.getCurrent(), fs.getName( tProgramStack[#tProgramStack] ) )
	  else
		  multishell.setTitle( multishell.getCurrent(), "shell" )
	  end
  end
  return result
	else
	 printError( "No such program" )
	 return false
	end
end
local function tokenise( ... )
	local sLine = table.concat( { ... }, " " )
local tWords = {}
	local bQuoted = false
	for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
		if bQuoted then
			table.insert( tWords, match )
		else
			for m in string.gmatch( match, "[^ \t]+" ) do
				table.insert( tWords, m )
			end
		end
		bQuoted = not bQuoted
	end
	return tWords
end
-- Install shell API
function shell.run( ... )
local tWords = tokenise( ... )
local sCommand = tWords[1]
if sCommand then
  return run( sCommand, table.unpack( tWords, 2 ) )
end
return false
end
function shell.exit()
	bExit = true
end
function shell.dir()
return sDir
end
function shell.setDir( _sDir )
sDir = _sDir
end
function shell.path()
return sPath
end
function shell.setPath( _sPath )
sPath = _sPath
end
function shell.resolve( _sPath )
local sStartChar = string.sub( _sPath, 1, 1 )
if sStartChar == "/" or sStartChar == "\\" then
  return fs.combine( "", _sPath )
else
  return fs.combine( sDir, _sPath )
end
end
function shell.resolveProgram( _sCommand )
-- Substitute aliases firsts
if tAliases[ _sCommand ] ~= nil then
  _sCommand = tAliases[ _sCommand ]
end
	-- If the path is a global path, use it directly
	local sStartChar = string.sub( _sCommand, 1, 1 )
	if sStartChar == "/" or sStartChar == "\\" then
	 local sPath = fs.combine( "", _sCommand )
	 if fs.exists( sPath ) and not fs.isDir( sPath ) then
   return sPath
	 end
  return nil
	end
  
  -- Otherwise, look on the path variable
	for sPath in string.gmatch(sPath, "[^:]+") do
	 sPath = fs.combine( shell.resolve( sPath ), _sCommand )
	 if fs.exists( sPath ) and not fs.isDir( sPath ) then
   return sPath
	 end
	end

-- Not found
return nil
end
function shell.programs( _bIncludeHidden )
local tItems = {}

-- Add programs from the path
	for sPath in string.gmatch(sPath, "[^:]+") do
	 sPath = shell.resolve( sPath )
  if fs.isDir( sPath ) then
   local tList = fs.list( sPath )
			for n=1,#tList do
				local sFile = tList[n]
	if not fs.isDir( fs.combine( sPath, sFile ) ) and
	   (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
	 tItems[ sFile ] = true
	end
   end
  end
	end
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
  table.insert( tItemList, sItem )
end
table.sort( tItemList )
return tItemList
end
local function completeProgram( sLine )
if #sLine > 0 and string.sub( sLine, 1, 1 ) == "/" then
	 -- Add programs from the root
	 return fs.complete( sLine, "", true, false )
	else
		local tResults = {}
		local tSeen = {}
		-- Add aliases
		for sAlias, sCommand in pairs( tAliases ) do
			if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
				local sResult = string.sub( sAlias, #sLine + 1 )
				if not tSeen[ sResult ] then
					table.insert( tResults, sResult )
					tSeen[ sResult ] = true
				end
			end
		end
		-- Add programs from the path
		local tPrograms = shell.programs()
		for n=1,#tPrograms do
			local sProgram = tPrograms[n]
			if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then
				local sResult = string.sub( sProgram, #sLine + 1 )
				if not tSeen[ sResult ] then
					table.insert( tResults, sResult )
					tSeen[ sResult ] = true
				end
			end
		end
		-- Sort and return
		table.sort( tResults )
		return tResults
	end
end
local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
	local tInfo = tCompletionInfo[ sProgram ]
	if tInfo then
		return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
	end
	return nil
end
function shell.complete( sLine )
	if #sLine > 0 then
		local tWords = tokenise( sLine )
		local nIndex = #tWords
		if string.sub( sLine, #sLine, #sLine ) == " " then
			nIndex = nIndex + 1
		end
		if nIndex == 1 then
			local sBit = tWords[1] or ""
			local sPath = shell.resolveProgram( sBit )
			if tCompletionInfo[ sPath ] then
				return { " " }
			else
				local tResults = completeProgram( sBit )
				for n=1,#tResults do
					local sResult = tResults[n]
					local sPath = shell.resolveProgram( sBit .. sResult )
					if tCompletionInfo[ sPath ] then
						tResults[n] = sResult .. " "
					end
				end
				return tResults
			end
		elseif nIndex > 1 then
			local sPath = shell.resolveProgram( tWords[1] )
			local sPart = tWords[nIndex] or ""
			local tPreviousParts = tWords
			tPreviousParts[nIndex] = nil
			return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
		end
	end
return nil
end
function shell.completeProgram( sProgram )
	return completeProgram( sProgram )
end
function shell.setCompletionFunction( sProgram, fnComplete )
	tCompletionInfo[ sProgram ] = {
		fnComplete = fnComplete
	}
end
function shell.getCompletionInfo()
	return tCompletionInfo
end
function shell.getRunningProgram()
if #tProgramStack > 0 then
  return tProgramStack[#tProgramStack]
end
return nil
end
function shell.setAlias( _sCommand, _sProgram )
tAliases[ _sCommand ] = _sProgram
end
function shell.clearAlias( _sCommand )
tAliases[ _sCommand ] = nil
end
function shell.aliases()
-- Copy aliases
local tCopy = {}
for sAlias, sCommand in pairs( tAliases ) do
  tCopy[sAlias] = sCommand
end
return tCopy
end
if multishell then
	function shell.openTab( ... )
		local tWords = tokenise( ... )
		local sCommand = tWords[1]
		if sCommand then
		 local sPath = shell.resolveProgram( sCommand )
		 if sPath == "rom/programs/shell" then
				return multishell.launch( tEnv, sPath, table.unpack( tWords, 2 ) )
			elseif sPath ~= nil then
				return multishell.launch( tEnv, "rom/programs/shell", sCommand, table.unpack( tWords, 2 ) )
			else
				printError( "No such program" )
			end
		end
	end
	function shell.switchTab( nID )
		multishell.setFocus( nID )
	end
end
	-- "shell"
	-- Print the header
	term.setBackgroundColor( bgColour )
	term.setTextColour( promptColour )
	print( os.version() )
	term.setTextColour( textColour )
	-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end
	-- Read commands and execute them
	local tCommandHistory = {}
	while not bExit do
		term.redirect( parentTerm )
		term.setBackgroundColor( bgColour )
		term.setTextColour( promptColour )
		write( shell.dir() .. "> " )
		term.setTextColour( textColour )
		local sLine = read( nil, tCommandHistory, shell.complete )
		table.insert( tCommandHistory, sLine )
		shell.run( sLine )
	end




———————————————
And here is the output file:

———————————————




--[[
THIS PROGRAM IS MIGRATED
]]--
function progf()
rednet.open("left")
while true do
  id ,msg = rednet.receive()
  if msg == "shutdown" then
	os.shutdown()
  end

end
end
function progs()
local multishell = multishell
local parentShell = shell
local parentTerm = term.current()
if multishell then
	multishell.setTitle( multishell.getCurrent(), "shell" )
end
local bExit = false
local sDir = (parentShell and parentShell.dir()) or ""
local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
local tAliases = (parentShell and parentShell.aliases()) or {}
local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
local tProgramStack = {}
local shell = {}
local tEnv = {
[ "shell" ] = shell,
[ "multishell" ] = multishell,
}
-- Colours
local promptColour, textColour, bgColour
if term.isColour() then
promptColour = colours.yellow
textColour = colours.white
bgColour = colours.black
else
promptColour = colours.white
textColour = colours.white
bgColour = colours.black
end
local function run( _sCommand, ... )
local sPath = shell.resolveProgram( _sCommand )
if sPath ~= nil then
  tProgramStack[#tProgramStack + 1] = sPath
  if multishell then
	  multishell.setTitle( multishell.getCurrent(), fs.getName( sPath ) )
  end
	 local result = os.run( tEnv, sPath, ... )
  tProgramStack[#tProgramStack] = nil
  if multishell then
	  if #tProgramStack > 0 then
		  multishell.setTitle( multishell.getCurrent(), fs.getName( tProgramStack[#tProgramStack] ) )
	  else
		  multishell.setTitle( multishell.getCurrent(), "shell" )
	  end
  end
  return result
	else
	 printError( "No such program" )
	 return false
	end
end
local function tokenise( ... )
	local sLine = table.concat( { ... }, " " )
local tWords = {}
	local bQuoted = false
	for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
		if bQuoted then
			table.insert( tWords, match )
		else
			for m in string.gmatch( match, "[^ \t]+" ) do
				table.insert( tWords, m )
			end
		end
		bQuoted = not bQuoted
	end
	return tWords
end
-- Install shell API
function shell.run( ... )
local tWords = tokenise( ... )
local sCommand = tWords[1]
if sCommand then
  return run( sCommand, table.unpack( tWords, 2 ) )
end
return false
end
function shell.exit()
	bExit = true
end
function shell.dir()
return sDir
end
function shell.setDir( _sDir )
sDir = _sDir
end
function shell.path()
return sPath
end
function shell.setPath( _sPath )
sPath = _sPath
end
function shell.resolve( _sPath )
local sStartChar = string.sub( _sPath, 1, 1 )
if sStartChar == "/" or sStartChar == "\\" then
  return fs.combine( "", _sPath )
else
  return fs.combine( sDir, _sPath )
end
end
function shell.resolveProgram( _sCommand )
-- Substitute aliases firsts
if tAliases[ _sCommand ] ~= nil then
  _sCommand = tAliases[ _sCommand ]
end
	-- If the path is a global path, use it directly
	local sStartChar = string.sub( _sCommand, 1, 1 )
	if sStartChar == "/" or sStartChar == "\\" then
	 local sPath = fs.combine( "", _sCommand )
	 if fs.exists( sPath ) and not fs.isDir( sPath ) then
   return sPath
	 end
  return nil
	end
  
  -- Otherwise, look on the path variable
	for sPath in string.gmatch(sPath, "[^:]+") do
	 sPath = fs.combine( shell.resolve( sPath ), _sCommand )
	 if fs.exists( sPath ) and not fs.isDir( sPath ) then
   return sPath
	 end
	end

-- Not found
return nil
end
function shell.programs( _bIncludeHidden )
local tItems = {}

-- Add programs from the path
	for sPath in string.gmatch(sPath, "[^:]+") do
	 sPath = shell.resolve( sPath )
  if fs.isDir( sPath ) then
   local tList = fs.list( sPath )
			for n=1,#tList do
				local sFile = tList[n]
	if not fs.isDir( fs.combine( sPath, sFile ) ) and
	   (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
	 tItems[ sFile ] = true
	end
   end
  end
	end
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
  table.insert( tItemList, sItem )
end
table.sort( tItemList )
return tItemList
end
local function completeProgram( sLine )
if #sLine > 0 and string.sub( sLine, 1, 1 ) == "/" then
	 -- Add programs from the root
	 return fs.complete( sLine, "", true, false )
	else
		local tResults = {}
		local tSeen = {}
		-- Add aliases
		for sAlias, sCommand in pairs( tAliases ) do
			if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
				local sResult = string.sub( sAlias, #sLine + 1 )
				if not tSeen[ sResult ] then
					table.insert( tResults, sResult )
					tSeen[ sResult ] = true
				end
			end
		end
		-- Add programs from the path
		local tPrograms = shell.programs()
		for n=1,#tPrograms do
			local sProgram = tPrograms[n]
			if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then
				local sResult = string.sub( sProgram, #sLine + 1 )
				if not tSeen[ sResult ] then
					table.insert( tResults, sResult )
					tSeen[ sResult ] = true
				end
			end
		end
		-- Sort and return
		table.sort( tResults )
		return tResults
	end
end
local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
	local tInfo = tCompletionInfo[ sProgram ]
	if tInfo then
		return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
	end
	return nil
end
function shell.complete( sLine )
	if #sLine > 0 then
		local tWords = tokenise( sLine )
		local nIndex = #tWords
		if string.sub( sLine, #sLine, #sLine ) == " " then
			nIndex = nIndex + 1
		end
		if nIndex == 1 then
			local sBit = tWords[1] or ""
			local sPath = shell.resolveProgram( sBit )
			if tCompletionInfo[ sPath ] then
				return { " " }
			else
				local tResults = completeProgram( sBit )
				for n=1,#tResults do
					local sResult = tResults[n]
					local sPath = shell.resolveProgram( sBit .. sResult )
					if tCompletionInfo[ sPath ] then
						tResults[n] = sResult .. " "
					end
				end
				return tResults
			end
		elseif nIndex > 1 then
			local sPath = shell.resolveProgram( tWords[1] )
			local sPart = tWords[nIndex] or ""
			local tPreviousParts = tWords
			tPreviousParts[nIndex] = nil
			return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
		end
	end
return nil
end
function shell.completeProgram( sProgram )
	return completeProgram( sProgram )
end
function shell.setCompletionFunction( sProgram, fnComplete )
	tCompletionInfo[ sProgram ] = {
		fnComplete = fnComplete
	}
end
function shell.getCompletionInfo()
	return tCompletionInfo
end
function shell.getRunningProgram()
if #tProgramStack > 0 then
  return tProgramStack[#tProgramStack]
end
return nil
end
function shell.setAlias( _sCommand, _sProgram )
tAliases[ _sCommand ] = _sProgram
end
function shell.clearAlias( _sCommand )
tAliases[ _sCommand ] = nil
end
function shell.aliases()
-- Copy aliases
local tCopy = {}
for sAlias, sCommand in pairs( tAliases ) do
  tCopy[sAlias] = sCommand
end
return tCopy
end
if multishell then
	function shell.openTab( ... )
		local tWords = tokenise( ... )
		local sCommand = tWords[1]
		if sCommand then
		 local sPath = shell.resolveProgram( sCommand )
		 if sPath == "rom/programs/shell" then
				return multishell.launch( tEnv, sPath, table.unpack( tWords, 2 ) )
			elseif sPath ~= nil then
				return multishell.launch( tEnv, "rom/programs/shell", sCommand, table.unpack( tWords, 2 ) )
			else
				printError( "No such program" )
			end
		end
	end
	function shell.switchTab( nID )
		multishell.setFocus( nID )
	end
end
	-- "shell"
	-- Print the header
	term.setBackgroundColor( bgColour )
	term.setTextColour( promptColour )
	print( os.version() )
	term.setTextColour( textColour )
	-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end
	-- Read commands and execute them
	local tCommandHistory = {}
	while not bExit do
		term.redirect( parentTerm )
		term.setBackgroundColor( bgColour )
		term.setTextColour( promptColour )
		write( shell.dir() .. "> " )
		term.setTextColour( textColour )
		local sLine = read( nil, tCommandHistory, shell.complete )
		table.insert( tCommandHistory, sLine )
		shell.run( sLine )
	end
end
parallel.waitForAll(progf , progs)

If you run this program , shell works but if you send this rednet message -> "shutdown" The computer will shutdown.
Sorry for bad english xd
Edited on 02 November 2015 - 04:19 PM
Creator #4
Posted 02 November 2015 - 05:26 PM
Well, this actually makes me see why its useful. Nice work. tArgs = {…} doesn't work because you have to declare it this way:

function progf(...)
  --stuff
end

You see the … ? These are the important ones.

Psssst: 1300th post!
Edited on 02 November 2015 - 04:25 PM
mentalr0b123 #5
Posted 02 November 2015 - 05:39 PM
It is not fixable… I guess…
KingofGamesYami #6
Posted 02 November 2015 - 05:40 PM
Well, this actually makes me see why its useful. Nice work. tArgs = {…} doesn't work because you have to declare it this way:

function progf(...)
  --stuff
end

You see the … ? These are the important ones.

Psssst: 1300th post!

How would you know which program(s) get which arguments?
Creator #7
Posted 02 November 2015 - 05:44 PM
It helps since it won't error when running the code and there is a reference to … Also, there is no way to pass arguments when using the parallel api.
H4X0RZ #8
Posted 02 November 2015 - 06:11 PM
It helps since it won't error when running the code and there is a reference to … Also, there is no way to pass arguments when using the parallel api.

There is


function func1(...)
  local a = {...}
  while true do 
    print("func1:"..unpack(a))
  end
end

function func2()
  while true do
    print("func2: I don't need arguments")
    sleep(0)
  end
end

parallel.waitForAll(function()
  func1("this ","is ","a ","test")
end,
func2)
Creator #9
Posted 02 November 2015 - 06:17 PM
Yeah, it works, even if it is kinda hacky.
mentalr0b123 #10
Posted 02 November 2015 - 06:19 PM
test1 program:

function test()
print("test")
end
test()
——————-
test2 program:
———————

function test()
print("test2")
end
test()
—————–
output file
—————–

--[[
THIS PROGRAM IS MIGRATED
]]--
function progf()
function test()
print("test")
end
test()
end

function progs()
function test()
print("test2")
end
test()
end

parallel.waitForAll(progf , progs)
 

That trouble is hard to solve… If you solve this trouble , post it here x)
Creator #11
Posted 02 November 2015 - 06:23 PM
Which trouble? Also, add the … in the progf and progs declarations.
mentalr0b123 #12
Posted 02 November 2015 - 06:29 PM
Which trouble? Also, add the … in the progf and progs declarations.
If sourcecode contains tArgs add function progf(…) ?
I will try
Edited on 02 November 2015 - 05:29 PM
Creator #13
Posted 02 November 2015 - 06:31 PM
Add it anyways. Its easier and won't harm.
mentalr0b123 #14
Posted 02 November 2015 - 06:33 PM
Add it anyways. Its easier and won't harm.
OMG Its worked xD Thanks for it D:
Creator #15
Posted 02 November 2015 - 06:37 PM
You're welcome!
mentalr0b123 #16
Posted 02 November 2015 - 06:38 PM
Updated xD
H4X0RZ #17
Posted 02 November 2015 - 08:13 PM
Yeah, it works, even if it is kinda hacky.

//Kinda Off-Topic
If that is "hacky" for you, you could try out my [shameless-self-promote]RandomUtils API[/shameless-self-promote].

local args = {...}

local function func1(...)
  --program code
end

local function func2(...)
  --other program code
end

parallel.waitForAll(
  _.bindn(func1,unpack(args)),
  _.bindn(func2,unpack(args))
)

Does that look less hacky for you?
Edited on 02 November 2015 - 07:14 PM
Creator #18
Posted 02 November 2015 - 08:18 PM
Looks even worse. But as long as it works.
Konlab #19
Posted 07 November 2015 - 08:38 PM
test1 program:

function test()
print("test")
end
test()
——————-
test2 program:
———————

function test()
print("test2")
end
test()
—————–
output file
—————–

--[[
THIS PROGRAM IS MIGRATED
]]--
function progf()
function test()
print("test")
end
test()
end

function progs()
function test()
print("test2")
end
test()
end

parallel.waitForAll(progf , progs)


That trouble is hard to solve… If you solve this trouble , post it here x)
Maybe you should try an environment trick.
Try this:
env1 = getfenv()
env2 = getfenv()
setfenv(func1,env1)
setfenv(func2,env2)

This will isolate the functions, they'll have their custom global vars (but when they ended you'll have to publish these and then probably conflicts will happen. For that you should maybe use two tables and publish global vars there)
Creator #20
Posted 07 November 2015 - 08:54 PM
That wouldn't work since the program only takes the content from the files. Where would it get the env tables from?
H4X0RZ #21
Posted 07 November 2015 - 09:10 PM
That wouldn't work since the program only takes the content from the files. Where would it get the env tables from?

getfenv() returns the environment of the current function which is the "main" program. But that would still cause conflicts because getfenv returns a pointer to the env, not a copy of the env. You have to copy (or even "deep copy") the env to get two independent tables.
Creator #22
Posted 07 November 2015 - 09:18 PM
Yeah, but why bother?
CoderPuppy #23
Posted 07 November 2015 - 10:02 PM
That wouldn't work since the program only takes the content from the files. Where would it get the env tables from?

getfenv() returns the environment of the current function which is the "main" program. But that would still cause conflicts because getfenv returns a pointer to the env, not a copy of the env. You have to copy (or even "deep copy") the env to get two independent tables.

Or use setmetatable({}, { __index = getfenv() }) to create a descended table.
Konlab #24
Posted 08 November 2015 - 09:02 AM
That wouldn't work since the program only takes the content from the files. Where would it get the env tables from?
Generate new ones with inheriting _G

newenv= setmetatable({},{__index = _G})

Or get the current env with getfenv()
Creator #25
Posted 08 November 2015 - 09:03 AM
The question is why? What does this bring?
Konlab #26
Posted 08 November 2015 - 09:09 AM
The question is why? What does this bring?
You avoid conflicts:

func1 = function()
 test = "hi"
 for i=1,15 do
  coroutine.yield()
 end
 A = #test
end
func2 = function()
 coroutine.yield()
 test = 5
end
Creator #27
Posted 08 November 2015 - 09:32 AM
This is why you use locals.
Konlab #28
Posted 08 November 2015 - 11:05 AM
This is why you use locals.
But you never know if you migrate some programs, which sometimes aren't yours
Creator #29
Posted 08 November 2015 - 11:14 AM
Then it's their problem. And to copy tables do this:

local function tablecopy(source,destination)
  source = type(source) == "table" and source or {}
  for i,v in pairs(source) do
    if type(v) == "table" then
	  destination[i] = {}
	  tablecopy(source[i],destination[i])
    else
	  destination[i] = v
    end
  end
end
env1 = tablecopy(getfenv(),{})
env2 = tablecopy(getfenv(),{})

Disclaimer: I am not responsible for recursive tables.
Konlab #30
Posted 08 November 2015 - 11:16 AM
Then it's their problem. And to copy tables do this:

local function tablecopy(source,destination)
  source = type(source) == "table" and source or {}
  for i,v in pairs(source) do
    if type(v) == "table" then
	  destination[i] = {}
	  tablecopy(source[i],destination[i])
    else
	  destination[i] = v
    end
  end
end
env1 = tablecopy(getfenv(),{})
env2 = tablecopy(getfenv(),{})

Disclaimer: I am not responsible for recursive tables.
No metatable support, no recursion support
Edited on 08 November 2015 - 10:18 AM
Creator #31
Posted 08 November 2015 - 11:20 AM
You're actually right.

local function tablecopy(source,destination)
  source = type(source) == "table" and source or {}
  for i,v in pairs(source) do
    if type(v) == "table" then
	  destination[i] = {}
	  local mt = getmetatable(v)
	  if mt and type(mt) == "table" then
	    setmetatable(destnation[i],mt)
	  end
	  tablecopy(v,destination[i])
    else
	  destination[i] = v
    end
  end
end

env1 = tablecopy(getfenv(),{})
env2 = tablecopy(getfenv(),{})