arg lua unpack

arg - ¿Lua desempaqueta el error?



lua function arguments (2)

He tropezado con un comportamiento extraño en la función de desempaquetado de Lua

table1 = {true, nil, true, false, nil, true, nil} table2 = {true, false, nil, false, nil, true, nil} a1,b1,c1,d1,e1,f1,g1 = unpack( table1 ) print ("table1:",a1,b1,c1,d1,e1,f1,g1) a2,b2,c2,d2,e2,f2,g2 = unpack( table2 ) print ("table2:",a2,b2,c2,d2,e2,f2,g2)

Salida:

table1: true nil true false nil nil nil table2: true false nil nil nil nil nil

El segundo desempaquetado entrega parámetros hasta el primer valor nulo. Podría vivir con eso. La primera mesa entrega 4? parámetros con uno siendo nil en el medio. Tiene 4 parámetros que no son nulos, pero no son los que se muestran.

¿Alguien podría explicar esto? Esto fue probado con codepad.org y lua 5.1


El problema se puede resolver simplemente especificando los índices inicial y final para unpack() y usando table.maxn() como el índice final:

table1 = {true, nil, true, false, nil, true, nil} a1,b1,c1,d1,e1,f1,g1 = unpack( table1, 1, table.maxn(table1) ) print ("table1:",a1,b1,c1,d1,e1,f1,g1) -->table1: true nil true false nil true nil

La verdadera razón de la discrepancia sobre cómo se manejan las dos tablas es en la lógica de determinar la longitud de la porción de la matriz de la tabla.

La función luaB_unpack() usa luaL_getn() que se define en términos de lua_objlen() que llama luaH_getn() para tablas. El luaH_getn() mira la última posición de la matriz, y si es nil realiza una búsqueda binaria para un límite en la tabla ("tal que t [i] no es nulo yt [i + 1] es nulo" ) La búsqueda binaria para el final de la matriz es la razón por la que table1 se maneja de manera diferente que la table2 .

Esto solo debería ser un problema si la última entrada en la matriz es nil .

Desde la Programación en Lua (pg.16) (Deberías comprar este libro.): Cuando una matriz tiene agujeros - elementos nulos dentro de ella - el operador de longitud puede asumir cualquiera de estos elementos nulos como marcador final. Por lo tanto, debe evitar usar el operador de longitud en las matrices que pueden contener agujeros.

El unpack() está utilizando el operador de longitud lua_objlen() , que "puede asumir cualquiera de [los] elementos nulos como el final" de la matriz.


2.2 - Valores y tipos

[...] La tabla de tipos implementa matrices asociativas, es decir, matrices que pueden indexarse ​​no solo con números, sino con cualquier valor (excepto nil). Las tablas pueden ser heterogéneas; es decir, pueden contener valores de todos los tipos (excepto nil) . [...]

Si se da nil a una entrada se romperá la enumeración de la tabla y sus variables no serán init correctamente.

Aquí hay un ejemplo simple que demuestra un comportamiento problemático :

table1 = {true, false, nil, false, nil, true, nil} for k,v in ipairs(table1) do print(k, v) end

salida:

1 true 2 false >Exit code: 0