Skip to content

Instantly share code, notes, and snippets.

@weswigham
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save weswigham/53e6f4e4f74376a5c26a to your computer and use it in GitHub Desktop.

Select an option

Save weswigham/53e6f4e4f74376a5c26a to your computer and use it in GitHub Desktop.

Revisions

  1. weswigham revised this gist May 15, 2014. 1 changed file with 17 additions and 6 deletions.
    23 changes: 17 additions & 6 deletions deepcopy.lua
    Original file line number Diff line number Diff line change
    @@ -4,19 +4,30 @@ local copymember = {
    local err = pcall(function() --handling the error is faster than getting debug info
    copy = loadstring(string.dump(val))
    end)
    if (err)
    if (not copy) then
    memo[val] = val
    return val
    end

    for i=1,i<debug.getinfo(val,'u').ups do
    debug.setupvalue(copy, i, debug.getupvalue(val, i))
    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(val, memo)
    return copymember[type(val)] and copymember[type(val)](val, memo) or val
    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)
    @@ -31,7 +42,7 @@ function deepcopy(orig, memo)
    end
    setmetatable(copy, memo[getmetatable(orig)] or deepcopy(getmetatable(orig), memo))
    else -- number, string, boolean, etc
    copy = memo[val] or copymember(orig, memo)
    copy = copymember(orig, memo)
    end
    return copy
    end
  2. weswigham created this gist May 13, 2014.
    37 changes: 37 additions & 0 deletions deepcopy.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    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 (err)
    return val
    end

    for i=1,i<debug.getinfo(val,'u').ups do
    debug.setupvalue(copy, i, debug.getupvalue(val, i))
    end
    memo[val] = copy
    return copy
    end
    }
    setmetatable(copymember, {__call = function(val, memo)
    return copymember[type(val)] and copymember[type(val)](val, memo) or val
    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 = memo[val] or copymember(orig, memo)
    end
    return copy
    end