Last active
August 29, 2015 14:01
-
-
Save weswigham/53e6f4e4f74376a5c26a to your computer and use it in GitHub Desktop.
A recursive deepcopy implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local copymember = { | |
['function'] = function(val, memo) | |
local copy; | |
local err = pcall(function() --handling the error is faster than getting debug info | |
copy = loadstring(string.dump(val)) | |
end) | |
if (not copy) then | |
memo[val] = val | |
return val | |
end | |
local info = debug.getinfo(val,'u'); | |
if info and info.ups and info.ups>0 then | |
for i=1,i<info.ups do | |
debug.setupvalue(copy, i, debug.getupvalue(val, i)) | |
end | |
end | |
memo[val] = copy | |
return copy | |
end, | |
['generic'] = function(val, memo) | |
return val | |
end | |
} | |
setmetatable(copymember, {__call = function(self, val, memo) | |
if copymember[type(val)] then | |
return copymember[type(val)](val, memo) | |
else | |
return copymember['generic'](val, memo) | |
end | |
end}) | |
function deepcopy(orig, memo) | |
memo = memo or {} | |
local orig_type = type(orig) | |
local copy | |
if orig_type == 'table' then | |
copy = {} | |
memo[orig] = copy | |
for orig_key, orig_value in next, orig, nil do | |
copy[memo[orig_key] or deepcopy(orig_key, memo)] = memo[orig_value] or deepcopy(orig_value, memo) | |
end | |
setmetatable(copy, memo[getmetatable(orig)] or deepcopy(getmetatable(orig), memo)) | |
else -- number, string, boolean, etc | |
copy = copymember(orig, memo) | |
end | |
return copy | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment