Gawk : 함수에 배열 전달


9

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

답변:


5

기능 매개 변수는 기능에 국한됩니다.

awk '
    function foo(x,y) {y=x*x; print "y in function: "y} 
    BEGIN {foo(2); print "y out of function: " y}
'
y in function: 4
y out of function: 

매개 변수보다 적은 수의 값을 함수에 전달하면 추가 매개 변수는 비어 있습니다. 때때로 다음과 같이 정의 된 함수가 표시 될 수 있습니다

function foo(a, b, c            d, e, f) {...

여기서 공백 뒤의 매개 변수는 로컬 변수이며 호출시 값을 취하지 않습니다.

로컬 배열에서 이것이 작동하지 않는 이유는 없습니다.

awk '
    function bar(x) {
        split("hello world", x)
        print "in: " x[1]
    }
    BEGIN {
        x[1]="world"
        bar()
        print "out: " x[1]}
'
in: hello
out: world

3

둔한 문서는 이 배열 참조에 의해 전달되는 것을 취소하지 않으며, 더 그 주위에 방법이 문서화. 동작은 gawk4.0.1 과 동일 합니다.

POSIX는 그 동작을 지정 하므로 awk다르게 동작 하는 구현을 찾지 못할 것 입니다.

해당 기능이 필요한 경우을 사용할 수 있습니다 perl. 스크립트를 로 번역 perl하는 도구 ( a2p)가 awk제공됩니다 perl.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.