Set Variables And Tables With Function

lua-users home
wiki

The following is an extension of the setfield function in "14.1. Accessing Global Variables with Dynamic Names" from the book "Programming in Lua" [1].

Instead of ensuring only the existence of an already created table, this function overwrites any given Table/Name -- as expected I think. And thanks to the fact that table-arguments are given by reference, you can use setvar() for any local table too.

function setvar(Table,Name,Value)

-- Table (table, optional); default is _G
-- Name (string); name of the variable--e.g. A.B.C ensures the tables A
--   and A.B and sets A.B.C to <Value>.
--   Using single dots at the end inserts the value in the last position
--   of the array--e.g. A. ensures table A and sets A[table.getn(A)]
--   to <Value>.  Multiple dots are interpreted as a string--e.g. A..B.
--   ensures the table A..B.
-- Value (any)
-- Compatible with Lua 5.0 and 5.1

   if type(Table) ~= 'table' then
      Table,Name,Value = _G,Table,Name
   end

   local Concat,Key = false,''

   string.gsub(Name,'([^%.]+)(%.*)',
      function(Word,Delimiter)
         if Delimiter == '.' then
            if Concat then
               Word = Key .. Word
               Concat,Key = false,''
            end
            if type(Table[Word]) ~= 'table' then
               Table[Word] = {}
            end
            Table = Table[Word]
         else
            Key = Key .. Word .. Delimiter
            Concat = true
         end
      end
   )

   if Key == '' then
      table.insert(Table,Value)
   else
      Table[Key] = Value
   end
end

Tests:

> Test = {}
> setvar(Test,'Index',1)
> setvar(Test,'Index.',22)
> setvar(Test,'Index.Index',333)
> table.foreach(Test,print)
Index   table: 0x689668
> table.foreach(Test.Index,print)
1       22
Index   333
>
> setvar(Test,'Index.Index.',4444)
> setvar(Test,'Index.Index.',4444)
> setvar(Test,'Index..',55555)
> setvar(Test,'Index..Index',666666)
> setvar(Test,'Index..Index.',7777777)
> setvar(Test,'Index..Index..',88888888)
> table.foreach(Test,print)
Index..Index..  88888888
Index.. 55555
Index   table: 0x689668
Index..Index    table: 0x684258
> table.foreach(Test.Index,print)
1       22
Index   table: 0x686270
> table.foreach(Test['Index..Index'],print)
1       7777777
>
> setvar(Test,'.Index',999999999)
> table.foreach(Test,print)
Index..Index..  88888888
Index.. 55555
Index   999999999
Index..Index    table: 0x684258
>
> setvar(Test,'',0)
> table.foreach(Test,print)
1       0
Index..Index..  88888888
Index..Index    table: 0x684258
Index   999999999
Index.. 55555

--MarkusHuber


RecentChanges · preferences
edit · history
Last edited May 28, 2007 10:56 pm GMT (diff)