matricks / bam

Bam is a fast and flexible build system. Bam uses Lua to describe the build process. It's takes its inspiration for the script files from scons. While scons focuses on being 100% correct when building, bam makes a few sacrifices to acquire fast full and incremental build times.
http://matricks.github.com/bam
Other
146 stars 47 forks source link

Calling :Copy() on a SettingsObject is not an actual copy. #88

Closed wc-duck closed 1 year ago

wc-duck commented 8 years ago

When doing a settings:Copy() the copy might not get the same order on elements in tables used as lists as the original.

Such as { "a", "b", "c" } might end up as { "b", "a", "c" }.

I might take a look at it myself if I get the time but I'll add an issue for it just so that it is not forgotten.

docbacardi commented 2 years ago

I have the same issue of mixed up lists, but for me it boils down to a combination of TableDeepCopy and TableFlatten.

local a = { 'a', 'b', 'c', 'd' }
local b = TableFlatten(TableDeepCopy(a))
for i,v in ipairs(b) do print(i,v) end

Above snippet gives me the following output:

1       d
2       a
3       b
4       c

Please note that d is now at position 1.

There is no problem if I use only TableDeepCopy or only TableFlatten to generate b.

docbacardi commented 2 years ago

Found it. :)

The problem was the use of lua_next in TableFlatten. In most cases it is possible to iterate over a sequence-like table with pairs or lua_next and get the elements in the expected order.

local a = { 'a', 'b', 'c', 'd' }
for k,v in pairs(a) do
  print(k,v)
end

Output:

1   a
2   b
3   c
4   d

Unfortunately this is not a guarantee. If the table is not a created in one go, but is the result of some work, the order might get disturbed. This can be easily demonstrated with the TableDeepCopy function.

local a = { 'a', 'b', 'c', 'd' }
for k,v in pairs(TableDeepCopy(a)) do
  print(k,v)
end

Output:

4   d
1   a
2   b
3   c

Please note that there is nothing wrong with TableDeepCopy. The same happens if you use a pure Lua function to make a copy of the table, like tablex.deepcopy from Penlight.

To keep the order of an input sequence T in TableFlatten it could loop over the elements from 1 to #T - much like ipairs does. There is only one problem. The old TableFlatten kept all key-value pairs, even those outside the sequence. With the ipairs approach they would be lost.

Here is the current behaviour:

local b = { a='a', b='b', c='c', 'd', 'e' }
print(table.concat(TableFlatten(b)))

Output:

deabc

With a new ipairs-like TableFlatten the output would be:

de

If my guess is right that TableFlatten is about sequences and keeping all key-value pairs is a side effect then please consider my patch. :-D

docbacardi commented 2 years ago

Can this be closed? PR-156 was merged.

matricks commented 1 year ago

Yes, it can be closed :)