Bloccato con GNU awk 3.1.6 e penso di aver aggirato i suoi bug di array ma ho ancora quello che sembra un problema di ambito in un programma awk a 600 righe. È necessario verificare la comprensione dell'ambito dell'array in awk per trovare il mio bug.
Dato questo codice illustrativo awk ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
stamperà ...
global result
Poiché le matrici vengono sempre passate alle funzioni per riferimento, tutte le matrici sono sempre globali. Non è possibile creare un array locale. È corretto? Non sono riuscito a trovare documenti che lo affermino esplicitamente.
Dal momento che sto eseguendo il debug, e 3.1.6 stesso ha riscontrato bug in quest'area, sto cercando di determinare dove si interrompono i bug di Awk e iniziano i miei.
Supplemento: perché ga [] funziona all'interno della funzione allora?
Prima di tutto, passare l'array alla funzione con non foo(ga)
è effettivamente necessario. Basta accedervi come garray[]
all'interno della funzione. Non vi è alcuna penalità misurabile nelle prestazioni nel farlo, tuttavia, aiuta nel debug e nella segnalazione degli errori.
Nel usando foo(ga)
, ga[]
è un sinonimo per l'array globale garray[]
. Invece di essere una copia locale di garray[]
, è semplicemente un puntatore a garray[]
, piuttosto come un collegamento simbolico è un puntatore a un file e quindi è possibile accedere allo stesso file (o array) con più di un nome.
Supplemento: chiarimento della risposta di Glenn Jackman
Mentre le matrici create al di fuori di una funzione sono globali alla funzione e possono essere passate ad essa o semplicemente citate al suo interno, le matrici create all'interno di una funzione rimangono effettivamente locali alla funzione e non visibili al di fuori di essa. La modifica dell'esempio di Mr. Jackman illustra questo ...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after:
Si noti che stiamo solo passando l' x[]
array (in realtà, solo un puntatore ad esso) a bar()
. L' y[]
array non esiste nemmeno finché non entriamo nella funzione.
Tuttavia, se dichiariamo y[]
includendolo nell'elenco degli bar()
argomenti senza assegnare nulla al di fuori della funzione, diventa visibile dopo aver chiamato bar(x,y)
...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello
Infine, se creiamo l' y[]
array all'esterno della funzione e lo passiamo con bar(x,y)
, l' split()
assegnazione all'interno della funzione sostituisce gli elementi dell'array ...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
y[1]="howdy"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before: howdy
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello