Perl은 해시와 패키지를 기반으로 하는 프로토타입 OOP를 지원하는 동적 언어입니다. 객체를 생성할 때는 일반적으로 bless를 사용합니다:
package Animal; sub new { my ($class, %args) = @_; return bless { %args }, $class; } sub speak { print "An animal makes a sound "; } package Dog; use parent 'Animal'; # 또는 our @ISA = ('Animal') sub speak { print "Woof! "; } my $dog = Dog->new(name => 'Rex'); $dog->speak; # 출력: Woof!
여기서 생성자 new는 객체 데이터와 해시를 생성하고 이를 클래스에 연결합니다. 메서드는 일반 서브프로그램으로 선언됩니다. 상속은 @ISA 또는 모듈 parent/base를 통해 가능하니다. Perl의 OOP는 유연하지만 엄격하지 않아서 추가적인 가능성과 미세한 조정이 가능합니다.
Perl에서 private/protected 구문이 없음을 고려할 때 객체의 프라이빗 속성/메서드를 어떻게 구현하는 것이 좋습니까?
답변: 내장된 메커니즘은 없지만, 프라이버시는 패키지 외부의 렉시컬 변수를 사용하거나 네이밍 규칙(_private)을 통해 달성됩니다. 예:
package Car; my $secret = 'hidden'; # 패키지에 대한 프라이빗 sub _private { ... } # 규칙: 외부에서 호출하지 않기
이런 방식은 접근을 막지는 않지만, 표준으로 여겨집니다.
이야기
프로젝트에서 다른 객체에 대한 참조 배열을 포함하는 객체가 정의되었습니다. 개발자들은 메서드를 $obj->method가 아닌 method($obj)로 호출하는 것을 잊어버려 의도치 않은 결과를 초래했습니다. 특히 상속 및 메서드 재정의 시 클래스가 잘못 식별되고 부모 메서드가 자식 메서드 대신 호출되는 문제가 발생했습니다.
이야기
객체 상태를 저장하기 위해 렉시컬 변수가 아닌 패키지 변수를 사용함으로써 상태 변경이 클래스의 모든 인스턴스에 반영되는 문제가 생겼습니다. 데이터가 객체마다 개별적이지 않고 공유되었기 때문입니다.
이야기
동적 클래스 로딩 시 상속을 위한 @ISA 변수를 암묵적으로 다루는 것은 큰 프로젝트에서 부모 목록이 제때 업데이트되지 않아 프로그램에서 메서드를 잃거나 잘못된 계층 구조를 얻는 경우가 발생했습니다.