Comprobación portátil de matriz

Comprobación portátil de matriz

Gawk tiene "isarray":

if (isarray(x))
  print "is array"
else
  print "is scalar"

Sin embargo, Mawk y "gawk --posix" no lo hacen:

fatal: function 'isarray' not defined

Esto puede causar problemas:

x
x[1]
fatal: attempt to use scalar 'x' as an array

O:

x[1]
x
fatal: attempt to use array 'x' in a scalar context

¿Puede Awk detectar una matriz sin utilizar la función "isarray"?

Respuesta1

No. Si pudiera, entonces no habría sido necesario que Gawk lo presentara.isarray().

Respuesta2

Tampoco creo que sea posible.

Pero agregaré que con Busybox awklas variables pueden ser tanto matrices como escalares. Allí está bien hacer:

a = "foo"; a["foo"] = "bar"

Sin embargo, cuando una variable se ha utilizado como una matriz, length()devuelve el número de elementos de la matriz, incluso si también se ha definido como un escalar (aunque se puede utilizar length(var "")para obtener la longitud del escalar), excepto cuando la variable se ha utilizado como una matriz. pasado como argumento a una función y asignado como escalar allí (podría considerarse como un error):

$ busybox awk 'BEGIN{a[1] = 1; a = "foo"; print length(a), length(a"")}'
1 3
$ busybox awk 'function f(x) {x = "xxx"; print x[1], length(x)}
               BEGIN{a[1]=1; x = "yyy"; print a[1], length(a); f(a)}'
1 1
1 3

Lástima, de lo contrario habría sido fácil definir una isarray()función allí. Todavía podemos saber si una variable es una matriz con al menos un elemento con

function isnonemptyarray(x) {
  return length(x) > 0 && length(x "") == 0
}

(suponiendo que la variable no se haya definido como matriz y escalar)

En cualquier caso, eso es busybox awkespecífico. length()no se puede utilizar en matrices de forma portátil. Se puede definir una array_length()función portátil con:

function array_length(a, tmp1, tmp2) {
  tmp1 = 0
  for (tmp2 in a) tmp1++
  return tmp1
}

Pero eso no se puede usar de forma portátil en variables que no son de matriz.

información relacionada