Preso com o GNU awk 3.1.6 e acho que trabalhei com seus bugs de matriz, mas ainda tenho o que parece ser um problema de escopo em um programa awk de 600 linhas. Preciso verificar a compreensão do escopo da matriz no awk para encontrar meu bug.
Dado este código awk ilustrativo ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
irá imprimir ...
global result
Como as matrizes sempre são passadas para as funções por referência, todas as matrizes são sempre globais. Não há como criar uma matriz local. Isso está correto? Não foi possível encontrar documentos que digam isso explicitamente.
Desde que eu estou depurando, e o próprio 3.1.6 conhece bugs nessa área, estou tentando determinar onde os bugs do awk param e os meus começam.
Suplementar: Por que o ga [] funciona dentro da função então?
Antes de tudo, passar o array para a função com foo(ga)
é realmente desnecessário. Basta acessá-lo como garray[]
dentro da função. Entretanto, não há penalidade mensurável de desempenho ao fazê-lo, e isso ajuda na depuração e no relatório de erros.
Em usar foo(ga)
, ga[]
é um sinônimo para a matriz global garray[]
. Em vez de ser uma cópia local garray[]
, é simplesmente um ponteiro para garray[]
, assim como um link simbólico é um ponteiro para um arquivo e, portanto, o mesmo arquivo (ou matriz) pode ser acessado com mais de um nome.
Suplementar: Esclarecimento da resposta de Glenn Jackman
Enquanto matrizes criadas fora de uma função são globais para a função e podem ser passadas para ela ou apenas referenciadas dentro dela, matrizes criadas dentro de uma função permanecem de fato locais na função e não são visíveis fora dela. Modificar o exemplo do Sr. Jackman ilustra isso ...
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:
Observe que estamos apenas passando o x[]
array (na verdade, apenas um ponteiro para ele) para bar()
. A y[]
matriz nem existe até entrarmos na função.
No entanto, se declararmos y[]
incluindo-o na bar()
lista de argumentos sem atribuir nada a ele fora da função, ele se torna visível após a chamada 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
Finalmente, se criarmos a y[]
matriz fora da função e a passarmos bar(x,y)
, a split()
atribuição dentro da função substituirá os elementos dessa matriz ...
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