Verificação portátil para matriz

3

Gawk tem "isarray":

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

No entanto Mawk e "gawk --posix" não:

fatal: function 'isarray' not defined

Isso pode causar problemas:

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

Ou:

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

Awk pode detectar um array sem usar a função "isarray"?

    
por Steven Penny 18.04.2017 / 05:36

2 respostas

3

Eu também não acho que seja possível.

Mas acrescentarei que com busybox awk , as variáveis podem ser arrays e escalares. Não há problema em fazer:

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

Quando uma variável foi usada como uma matriz, length() retorna o número de elementos na matriz, mesmo que ela também tenha sido definida como escalar (embora você possa usar length(var "") para obter o comprimento da matriz). escalar), exceto quando a variável foi passada como um argumento para uma função e atribuída como escalar (pode ser considerada como um bug):

$ 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

Pena que, de outra forma, teria sido fácil definir uma função isarray() lá. Ainda podemos dizer se uma variável é um array com pelo menos um elemento com

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

(assumindo que a variável não foi definida como array e escalar)

Em qualquer caso, isso é busybox awk specific. length() não pode ser usado nos arrays de forma portável. Pode-se definir uma função array_length() portável com:

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

Mas isso não pode ser usado portavelmente em variáveis não matriciais.

    
por 19.04.2017 / 12:56
1

Não. Se pudesse, então, não haveria necessidade de o gawk introduzir isarray() .

    
por 18.04.2017 / 15:36