ポータブルアレイチェック

ポータブルアレイチェック

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

いいえ。もしそれが可能であれば、gawkが導入する必要はなかったでしょう。isarray()

答え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()。変数が少なくとも1つの要素を持つ配列であるかどうかはまだわかります。

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
}

しかし、これは配列以外の変数では移植可能に使用することはできません。

関連情報