Set Variables And Tables With Function |
|
|
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]. |
|
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. |
|
{{{ function setvar(Table,Name,Value) |
|
{{{!Lua function setvar(Table,Name,Value) |
|
-- 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. |
|
-- Compatible with Lua 5.0 and 5.1 |
|
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 |
|
string.gsub(Name,'([^%.]+)(%.*)',function(Word,Delimiter) |
|
local Concat,Key = false,'' |
|
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 |
|
) |
|
if Key == '' then table.insert(Table,Value) else Table[Key] = Value |
|
end }}} |
|
Tests: |
|
-- 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 |
|
--MarkusHuber |
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