질문의 배경:
Perl의 객체 지향 프로그래밍은 패키지(package)와 bless 함수에 의한 참조 결합을 기반으로 구현됩니다. 상속은 Perl이 메서드를 검색하는 패키지를 자동으로 식별하는 @ISA 배열을 통해 이루어집니다. 검색 메커니즘은 일반적으로 MRO(메서드 해결 순서)라고 불립니다.
문제:
@ISA 배열의 혼란스러운 관리와 메서드 검색 순서를 이해하지 않은 채 SUPER를 사용하는 것은 종종 오류, 중복 호출 또는 원하는 기능을 재정의하지 못하는 결과를 초래합니다. AUTOLOAD의 사용은 무한 루프 검색의 함정을 피하기 위해 제어가 필요합니다.
해결책:
코드 예:
package Animal; sub speak { print "Animal speaks "; } package Dog; our @ISA = qw(Animal); sub speak { print "Dog barks! "; shift->SUPER::speak(); # 부모 메서드 호출 } my $dog = bless {}, 'Dog'; $dog->speak;
주요 특징:
상속 체인에 동일한 메서드 이름을 가진 여러 부모 패키지가 있을 경우 어떤 메서드가 호출됩니까?
검색은 왼쪽에서 오른쪽으로 진행되며(@ISA에 선언된 순서), 최초로 발견된 메서드가 호출됩니다.
특정 메서드가 상속 트리에 없고 AUTOLOAD가 단 하나의 부모만 구현되었을 경우 어떻게 됩니까?
Perl은 메서드 검색 체인에서 최초로 발견된 클래스의 AUTOLOAD만 호출합니다. @ISA에서 먼저 나타나지 않은 다른 AUTOLOAD는 작동하지 않습니다.
체인 조회 메서드의 순서를 실시간으로 변경할 수 있나요?
기술적으로 @ISA 배열을 런타임에서 변경할 수 있지만, 이는 취약성과 추적하기 어려운 오류를 초래합니다. 이러한 접근 방식은 특정 경우에만 권장됩니다.
동일한 메서드 이름을 가진 여러 부모 클래스를 사용할 때, @ISA의 순서가 수동으로 예측할 수 없이 변경되며, 메서드는 SUPER를 호출하여 무한 재귀를 초래합니다.
장점:
단점:
@ISA의 명시적인 선언을 통해서만 수정하고, 다중 상속이 필요한 경우 mro::Concise나 Class::C3 같은 전문 모듈을 사용합니다.
장점:
단점: