Set Variables And Tables With Function

lua-users home
wiki

Difference (from prior major revision) (minor diff, author diff)

Changed: 1c1
Started with the setfield function from the book "Programming in Lua" chapter 14.1 page 120 here is my final result. For those not familiar with the book, would you please summarize the purpose of this function?
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].

Changed: 3c3
Instead of ensure only the existence of an already created table this function overwrites any given Table/Name - as expected I think.
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.

Changed: 5,6c5,6
{{{
function setvar(Table,Name,Value)
{{{!Lua
function setvar(Table,Name,Value)

Changed: 9,11c9,14
-- Name (string); name of the variable e.g. A.B.C ensures the table A and A.B and sets A.B.C to <Value>
-- 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
-- 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.

Added: 12a16
-- Compatible with Lua 5.0 and 5.1

Changed: 14,18c18,20
if type(Table)~='table' then
Table,Name,Value = _G,Table,Name
end

local Concat,Key = false,''
if type(Table) ~= 'table' then
Table,Name,Value = _G,Table,Name
end

Changed: 20c22
string.gsub(Name,'([^%.]+)(%.*)',function(Word,Delimiter)
local Concat,Key = false,''

Changed: 22,41c24,38
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
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

Added: 42a40
)

Added: 43a42,45
if Key == '' then
table.insert(Table,Value)
else
Table[Key] = Value

Added: 44a47,48
end
}}}

Added: 45a50
Tests:

Changed: 47,73c52,93
-- the following lines are only for tests

Test={}

setvar(Test,'Index',1)
setvar(Test,'Index.',22)
setvar(Test,'Index.Index',333)

-- dump content of Test here

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)

-- dump content of Test here

setvar(Test,'.Index',999999999)

-- dump content of Test here

setvar(Test,'',0)

-- dump content of Test and here

{{{
> 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

Added: 75a96
--MarkusHuber

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 9:56 pm GMT (diff)