Utknąłem z GNU awk 3.1.6 i myślę, że pracowałem nad jego błędami tablicowymi, ale nadal mam coś, co wygląda jak problem z zasięgiem w 600-liniowym programie awk. Potrzebuję zweryfikować zrozumienie zakresu tablicy w awk, aby znaleźć mój błąd.
Biorąc pod uwagę ten przykładowy kod awk ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
wydrukuje ...
global result
Ponieważ tablice są zawsze przekazywane do funkcji przez odwołanie, wszystkie tablice są zawsze globalne. Nie ma możliwości utworzenia lokalnej tablicy. Czy to jest poprawne? Nie udało mi się znaleźć dokumentów, które wyraźnie to mówią.
Ponieważ debuguję, a sama wersja 3.1.6 znała błędy w tym obszarze, staram się ustalić, gdzie błędy awk kończą się, a moje zaczynają.
Uzupełnienie: Dlaczego ga [] działa wtedy w funkcji?
Po pierwsze, przekazanie tablicy do funkcji za pomocą foo(ga)
jest w rzeczywistości niepotrzebne. Po prostu uzyskaj do niej dostęp jak garray[]
w funkcji. Nie ma jednak mierzalnego ograniczenia wydajności i pomaga w debugowaniu i raportowaniu błędów.
W użyciu foo(ga)
, ga[]
jest synonimem globalnej tablicy garray[]
. Zamiast być lokalną kopią garray[]
, jest po prostu wskaźnikiem do garray[]
, podobnie jak dowiązanie symboliczne jest wskaźnikiem do pliku, dzięki czemu można uzyskać dostęp do tego samego pliku (lub tablicy) pod więcej niż jedną nazwą.
Uzupełnienie: wyjaśnienie odpowiedzi Glenna Jackmana
Podczas gdy tablice utworzone poza funkcją są globalne dla funkcji i mogą być do niej przekazywane lub po prostu do niej odwoływane, tablice utworzone wewnątrz funkcji faktycznie pozostają lokalne dla funkcji i nie są widoczne poza nią. Modyfikacja przykładu pana Jackmana ilustruje to ...
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:
Zauważ, że przekazujemy tylko x[]
tablicę (właściwie wskaźnik do niej) do bar()
. y[]
Array nawet nie istnieje, dopóki mamy wewnątrz funkcji.
Jeśli jednak zadeklarujemy, dołączając y[]
go do bar()
listy argumentów bez przypisywania czegokolwiek poza funkcją, staje się widoczny po wywołaniu 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
Wreszcie, jeśli tworzymy y[]
tablicę poza funkcją i przekazujemy ją bar(x,y)
, split()
przypisanie wewnątrz funkcji zastępuje elementy tej tablicy ...
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