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

{Solved} Recursive Readonlytable

Started by cyanisaac, 31 January 2016 - 06:54 PM
cyanisaac #1
Posted 31 January 2016 - 07:54 PM
EDIT: This is solved. Working function:

local function readonlytable(table)
   return setmetatable({}, {
	 __index = table,
	 __newindex = function(table, key, value)
					error("Attempt to modify read-only table")
				  end,
	 __metatable = false
   });
end

function packagePrivateTable(tbl)
  for key, value in pairs(tbl) do
	if type(value) == 'table' then
	  tbl[key] = packagePrivateTable(tbl[key])
	end
  end
  return readonlytable(tbl)
end


Original PostI am trying to make a recursive readonlytable() that will make tables inside of the original tables into read-only tables.

This is what I have so far.


local function readonlytable(table)
   return setmetatable({}, {
	 __index = table,
	 __newindex = function(table, key, value)
					error("Attempt to modify read-only table")
				  end,
	 __metatable = false
   });
end

function packagePrivateTable(tbl)
  local workingTable = {}
  local argTable = tbl
  local workingCount = 0

  for key, value in pairs(argTable) do
	if type(key) == 'table' then
	  workingTable[key] = packagePrivateTable(argTable[key])
	end
  end
  return readonlytable(workingTable)
end


However when running packagePrivateTable on a table, it returns a table with nothing in it (attempting to access values returns nil). What am I doing wrong here?
Edited on 31 January 2016 - 07:24 PM
MKlegoman357 #2
Posted 31 January 2016 - 08:14 PM
That's because in your for loop you only add tables to your 'workingTable'. Also, you can use 'value' instead of 'argTable[key]' in the loop. And I don't really see the point of 'argTable' variable, you could just use 'tbl'.
Edited on 31 January 2016 - 07:16 PM
cyanisaac #3
Posted 31 January 2016 - 08:23 PM
Thank you for the help MKlegoman357. This is my final function (along with the readonlytable function, which I grabbed off of a lua wiki somewhere, that this function requires:

local function readonlytable(table)
   return setmetatable({}, {
     __index = table,
     __newindex = function(table, key, value)
                    error("Attempt to modify read-only table")
                  end,
     __metatable = false
   });
end

function packagePrivateTable(tbl)
  for key, value in pairs(tbl) do
    if type(value) == 'table' then
      tbl[key] = packagePrivateTable(tbl[key])
    end
  end
  return readonlytable(tbl)
end

Hopefully others find this useful.