Переносимая проверка для массива

Переносимая проверка для массива

В Gawk есть «isarray»:

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

Однако Mawk и «gawk --posix» этого не делают:

fatal: function 'isarray' not defined

Это может вызвать проблемы:

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

Или:

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

Может ли Awk обнаружить массив без использования функции «isarray»?

решение1

Нет. Если бы это было возможно, то не было бы необходимости в представлении gawkisarray().

решение2

Я тоже не думаю, что это возможно.

Но я добавлю, что с busybox awkпеременные могут быть как массивами, так и скалярами. Там можно сделать:

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

Однако если переменная используется как массив, length()возвращается количество элементов в массиве, даже если она также была определена как скаляр (хотя вы можете использовать , length(var "")чтобы получить длину скаляра), за исключением случаев, когда переменная была передана в качестве аргумента функции и назначена ей как скаляр (это может считаться ошибкой):

$ 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

Жаль, иначе было бы легко определить isarray()функцию там. Мы все еще можем сказать, является ли переменная массивом с хотя бы одним элементом с

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

(предполагается, что переменная не была определена одновременно как массив и скаляр)

В любом случае, это busybox awkспецифично. length()не может быть использовано в массивах переносимо. Можно определить переносимую array_length()функцию с помощью:

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

Однако это не может быть использовано переносимо для переменных, не являющихся массивами.

Связанный контент