Застрял в GNU awk 3.1.6 и думаю, что я обошел его ошибки массива, но все еще имеет то, что похоже на проблему с областью действия в 600-строчной программе awk. Нужно проверить понимание области действия массива в awk, чтобы найти мою ошибку.
Учитывая этот иллюстративный код awk ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
напечатает ...
global result
Поскольку массивы всегда передаются функциям по ссылке, то все массивы всегда являются глобальными. Нет способа создать локальный массив. Это правильно? Не удалось найти документы, которые прямо говорят об этом.
Так как я отлаживаюсь, а сама версия 3.1.6 знает ошибки в этой области, я пытаюсь определить, где ошибки awk исчезают, и начинаются мои.
Дополнение: Почему тогда ga [] работает внутри функции?
Прежде всего, передача массива в функцию с помощью foo(ga)
фактически не требуется . Просто получите доступ к нему как garray[]
внутри функции. Тем не менее, в этом нет никакого измеримого снижения производительности, и это помогает в отладке и сообщении об ошибках.
В использовании foo(ga)
, ga[]
является синонимом для глобального массива garray[]
. Вместо того, чтобы быть локальной копией garray[]
, это просто указатель на garray[]
, а символическая ссылка - это указатель на файл и, следовательно, один и тот же файл (или массив) может быть доступен под более чем одним именем.
Дополнение: разъяснение ответа Гленна Джекмана
В то время как массивы, созданные вне функции, являются глобальными для функции и могут быть переданы ей или просто упомянуты внутри нее, массивы, созданные внутри функции, действительно остаются локальными для функции и не видны вне ее. Изменение примера мистера Джекмана иллюстрирует это ...
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:
Обратите внимание, что мы только передаем x[]
массив (фактически, просто указатель на него) bar()
. y[]
Массив даже не существует , пока мы не получим внутри функции.
Однако, если мы объявим y[]
, включив его в bar()
список аргументов, не назначая ему ничего вне функции, оно станет видимым после вызова 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
Наконец, если мы создадим y[]
массив вне функции и передадим его bar(x,y)
, split()
присваивание внутри функции заменяет элементы этого массива ...
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