트레이트 – 07.복사·붙여넣기 메커니즘

복사·붙여넣기 메커니즘(copy’n’paste mechanism)

앞 장에서 클래스에 조합된 트레이트는 컴파일할 때(compile time) 트레이트의 모든 프로퍼티와 메소드를 복사·붙여넣기 메커니즘과 같이 해당 클래스에 배치한다고 하였습니다.

아래의 예제를 통해 복사·붙여넣기 메커니즘이 어떻게 움직이는지 살펴보기로 하겠습니다. 이 예제는 복사·붙여넣기 메커니즘을 설명하기 위한 실험적인 코드이므로 전혀 실용적이지도 않고 이와 같은 구조로 작성해서도 안될 것으로 보입니다.

$a->printA()의 실행 결과는 ‘A2’입니다. 클래스의 상속 개념으로 보면 전혀 이해가 되지 않는 결과입니다. private로 지정된 트레이트의 printA1 메소드를 클래스 A에서 아무런 제한 없이 접근하고 있습니다. 그리고 클래스 A에 조합되기 전까지는 서로 연관이 없는 트레이트 A1과 A2가 서로 넘나드는데 아무런 제한이 없습니다. 상속의 개념으로는 이해할 수 없지만 복사·붙여넣기 메커니즘으로 살펴보면 아무 문제가 없습니다. 컴파일할 때 트레이트 A1과 A2는 복사(copy)되어 클래스에 붙여넣기(paste) 되며, 이 후 소스 코드에서 트레이트 A1과 A2가 제거되기 때문에 런타임에서는 트레이트의 존재를 전혀 알 수 없습니다.

그러나 트레이트는 서로 다른 다양한 구성의 프로그램 내에서 필요한 만큼 클래스에 조합하여 자유롭게 재사용되어지는 것이기 때문에, 복사·붙여넣기가 되었다고 트레이트가 물리적으로 사라지는 것은 아닙니다. 관련하여 런타임에서는 트레이트를 구분할 수 없으나 컴파일 타임에서 트레이트 로컬 스코프와 관련하여 염두에 두어야 할 부분이 있으며, 이와 관련된 사항들은 ‘트레이트의 로컬 스코프’ 글에서 자세히 살펴보겠습니다.

‘충돌 방지 연산자’ 글에서 살펴보겠지만 as 연산자로 트레이트 메소드의 이름을 변경했다고 해서 원래의 트레이트 메소드 이름이 변경되지 않으며, 메소드 이름에 대한 원래의 트레이트 메소드의 참조도 변경되지 않습니다.

트레이트는 오직 use 문을 통해 클래스와 연결되어지며, 이 후 플래트닝 속성(flattening property)으로 필터링하여 클래스에 배치하게 될 구성을 확정한 후, 최종적으로 확정된 부분을 선택(복사)하여 클래스에 배치(붙여넣기)하게 됩니다.

복사·붙여넣기 메커니즘

따라서 위 예제를 컴파일한 후의 상태를 의미 상으로 풀어보면 다음과 같다고 볼 수 있습니다.

위와 같이 배치하고 나면, $a->printA()의 실행 결과는 ‘A2’가 나오는 것은 당연한 일이 됩니다. 이 예제는 단순한 구조이므로 위와 같이 설명할 수 있으나 여기에 다양한 플래트닝 속성이 적용되면 좀 더 복잡해지게 됩니다만 기본 개념은 동일합니다.

답글 남기기