네임스페이스 – 09.이름변환규칙

네임스페이스 기능을 적용하게 되면 클래스/함수/상수의 이름은 동일하지만 서로 다른 네임스페이스에 소속될 수 있기 때문에 각 이름이 소속된 네임스페이스를 명확히 지정할 필요가 있습니다.

이름변환규칙name resolution rule

‘식별자 관련 용어 정리’ 글에서 살펴보았듯이 네임스페이스 엘리먼트(클래스/함수/상수)를 참조하는 방식에는 절대-이름fully qualified name, 상대-이름qualified name엘리먼트-이름unqualified name에 의한 참조 방식이 있습니다.

어떤 방식의 이름이 되었든지 컴파일 과정에서 모두 선행 백슬래시를 제거한 절대-이름fully qualified name으로 변환됩니다.

아래와 같은 이름변환규칙name resolution rule에 따라 각 참조 방식별로 다르게 적용되어 변환됩니다.

절대-이름fully qualified name

절대-이름fully qualified name은 항상 선행 네임스페이스 구분자를 제거한 이름으로 변환됩니다. 예를 들어 \A\B는 A\B로 변환됩니다.

상대-이름qualified name

상대-이름qualified name의 경우, 이름의 첫 번째 세그먼트segment가 현재 클래스/네임스페이스 임포트 테이블에 따라 변환됩니다. 예를 들어 네임스페이스 A\B\C를 C로 임포트한 경우 이름 C\D\E는 A\B\C\D\E로 변환됩니다.

상대-이름qualified name의 경우, 임포트 규칙이 적용되지 않으면 현재 네임스페이스가 이름 앞에 추가됩니다. 예를 들어 네임스페이스 A\B 내의 이름 C\D\E는 A\B\C\D\E로 변환됩니다.

예제 – 다른 네임스페이스에 정의된 동일한 함수 이름

동일한 이름 my\func와 같이 선행 백슬래시가 없는 상대-이름qualified name인 경우, 먼저 my에 해당하는 별칭의 임포트 문이 있으면 my에는 해당 별칭이 적용됩니다.

이에 따라 foo\my\func에서 foo는 임포트 문에 있기 때문에 별칭 foo의 원래 이름인 bar이 적용되어 bar\my\func로 이름 변환됩니다.

그러나 my\func에서 my는 별칭 my에 해당하는 임포트 문이 없기 때문에 현재 네임스페이스 이름인 foo가 my\func 앞에 추가되어 foo\my\func로 이름 변환됩니다.

namespace 키워드 상대-이름relative name

namespace 키워드로 시작하는 상대-이름relative name은 항상 namespace 키워드를 현재 네임스페이스로 대체된 이름으로 변환됩니다. 이름이 전역 네임스페이스global namespace에 있으면 선행 namespace\ 는 제거됩니다.

예를 들어 namespace\A가 네임스페이스 X\Y 내에 있다면 X\Y\A로 변환됩니다.

동일한 이름이 전역 네임스페이스 내에 있다면 A로 변환됩니다.

엘리먼트-이름unqualified name

네임스페이스 구분자namespace separator가 없는 엘리먼트-이름unqualified name의 경우, 해당 심볼 유형(클래스/함수/상수)에 대한 현재 임포트 테이블에 따라 이름이 변환됩니다. 즉, 클래스/네임스페이스 임포트 테이블에 따라 클래스와 같은 이름이 변환되고, 함수 임포트 테이블에 따라 함수 이름이, 상수 임포트 테이블에 따라 상수 이름이 변환됩니다.

<심볼 유형별 적용되는 임포트 테이블>
심볼 유형 클래스 함수 상수
임포트 테이블 클래스/네임스페이스
임포트 테이블
함수 임포트 테이블 상수 임포트 테이블
임포팅 규칙이 적용되는 클래스/함수/상수

예를 들어 use A\B\C; 선언 후 new C()이 실행되면 클래스 C는 A\B\C로 변환되어 실행됩니다. 마찬가지로, use function A\B\func; 선언 후; func()이 실행되면 함수 func는 A\B\func으로 변환되어 실행됩니다.

임포팅 규칙이 적용되지 않는 클래스

임포트 규칙이 적용되지 않고 이름이 클래스와 같은 심볼을 참조하면 현재 네임스페이스가 이름 앞에 추가됩니다. 예를 들어 네임스페이스 A\B 내의 new C()는 이름 A\B\C로 변환됩니다.

임포팅 규칙이 적용되지 않는 함수/상수

전역 공간이 아닌 네임스페이스 내에서 임포트 규칙이 적용되지 않는 함수 또는 상수를 참조하는 경우에는 런타임runtime* 아래와 같은 순서에 의해 이름이 변환됩니다.

  1. 현재 네임스페이스에 정의된 함수를 확인 후 참조
  2. 전역 함수(built-in or user-defined function)를 확인 후 참조

예를 들어, 코드가 네임스페이스 A\B에 있다고 가정하면 다음은 함수 func()의 참조를 위한 연결 순서입니다.

  1. 먼저 현재 네임스페이스 A\B\func()에서 함수를 찾아 확인되면 해당 함수를 참조합니다.

  1. 현재 네임스페이스 A\B에서 func() 함수를 찾을 수 없다면, 전역 함수 func()를 찾아 확인되면 참조하고 해당 함수가 없으면 오류가 발생합니다.

예제 – 다른 네임스페이스에 정의된 동일한 클래스 이름

동일한 클래스 이름 cls와 같이 백슬래시가 없는 엘리먼트-이름unqualified name인 경우, 먼저 cls에 해당하는 별칭의 임포트 문이 있으면 cls에는 해당 별칭이 적용됩니다.

이에 따라 foo::func에서 foo는 임포트 문에 있기 때문에 별칭 foo의 원래 이름인 bar\cls이 적용되어 bar\cls로 이름 변환되어 bar\cls::func()가 호출됩니다.

그러나 cls::func에서 cls는 별칭 cls에 해당하는 임포트 문이 없기 때문에 현재 네임스페이스 이름인 foo가 cls 앞에 추가되어 foo\cls::func로 이름 변환되어 foo\cls::func()가 호출됩니다.

답글 남기기