그러나 전체 자란처럼 로그인 서브 루틴을 치료하는 경우 방법 (나는 첫 번째 예에서와 같이), 당신이 방법은 서브 루틴의 첫 번째 매개 변수로 자신의 클래스 개체를 전달할 수 있음을 기억해야합니다.
sub login {
my $self = shift; #Pointer to the Another_package object I'm using
my $user = shift;
my $password = shift; #I just love lining things up!
$self->{USER} = $user; #Bad way of doing it.
$self->{PASSWD} = $password;
... #Some processing.
return $user;
}
왜 #Bad way of doing it
코멘트 :
따라서, 당신은 이런 식으로 뭔가를해야 할 것? 당신은 정말로 내부를 가능한 한 분리 된 상태로 유지하기를 원하기 때문입니다. 이렇게하면 Another_package
클래스의 구조를 변경하면 변경 사항이 코드의 특정 부분에서 분리됩니다. 디버깅이 훨씬 쉬워집니다.
될 것 로그인 서브 루틴을 작성하는 더 좋은 방법 :이 예에서
sub Login { #In standard Perl, methods are capitalized.
my $self = shift; #Pointer to Another_package object
my $user = shift; #Allow user to pass user and password in constructor
my $password = shift; #I just love lining things up!
$self->User($user); #Way better: This is a setter/getter method
$self->Password($password);
... #Some processing.
return $user;
}
, 내 사용자 이름과 암호를 설정하는 세터/getter 메소드를 사용하고 있습니다. 이 방법으로, 나는 그들이 실제로 내 물건에 어떻게 저장되는지 걱정할 필요가 없다.
setter/getter 메소드를 사용하는 Another_Package
모듈은 다음과 같습니다. 원하는 경우 사용자가 새 생성자를 호출 할 때 사용자와 암호를 전달할 수있게되었습니다. 내 새로운 생성자 서브 루틴
package Another_package;
sub new {
my $class = shift;
my $user = shift;
my $password = shift;
my $self = {};
bless $self, $class;
$self->User($user);
$self->Password($password);
...
return $self;
}
sub Login {
my $self = shift;
my $user = shift;
my $pass = shift;
$self->Password($pass);
if (not defined $self->User($user)) {
croak qq(Cannot log in without a user ID);
}
...
if ($login_successful) {
return $self->User; #Or maybe a session instant
else {
return;
}
}
공지 사항 나는 $self
익명 해시 (my $self = {}
)를 만들고 나는 즉시 그것을 축복. 자, $self
은 이미 패키지 객체이며, 많은 객체를 setter/getter 메소드로 호출하여 여러 필드를 설정할 수 있습니다. 내 새로운 생성자는 내 실제 Another_module 객체가 어떤 모습인지 전혀 알 수 없습니다.
내 로그인 메서드 서브 루틴에서는 사용자 및 암호를 설정하는 데에도 동일한 setter/getter 메서드를 사용합니다. 다시, 내 로그인 메서드는 이러한 필드이 개체에 저장되는 방법에 대해 아무것도 모릅니다.
내 눈에 보일 수도있는 또 하나의 점은 내 모듈에 $login_successful
이라는 스칼라를 설정한다는 것입니다. 로그인 성공 여부를 확인할 수 있습니다. Perl에서는 메서드가 실패하면 아무 것도 반환하지 않거나 성공하면 반환하지 않는 것이 일반적입니다. 이 방법으로 사용자 프로그램은 호출이 성공했는지 실패했는지 확인하기 위해 테스트 할 수 있습니다.예를 들어, 로그인에 실패 아마도 경우, 사용자는 포기하기 전에 몇 가지 기본 암호를 시도 할 수 있습니다 :
my $package_obj = Another_package->new($user, $password);
my $foo = $package_obj->Login;
if (not defined $foo) {
foreach my $password qw(swordfish s3x mon3y 7ucky) {
$package_obj->Password($password);
last if $foo = $package_obj->Login;
}
if (not defined $foo) {
die "I don't know the password :-(";
}
}
그래서, 내 세터/getter 메소드처럼 중요시하는 점은 무엇입니까
? 그들은 실제로 매우 간단 위치 : sub User {
my $self = shift;
my $user = shift;
if(defined $user) {
$self->{USER_INFO}->{USER} = $user;
}
return $self->{USER_INFO}->{USER};
}
sub Password {
my $self = shift;
my $pass = shift;
if (defined $password) {
$self->{USER_INFO}->{PASSWORD} = $pass;
}
return $self->{USER_INFO}->{PASSWORD};
}
가 왜 $self->{USER_INFO}->{USER}
에서 $user
하지 $self->{USER}
를 저장합니까? 전혀 이유가 없습니다. 그러나 나머지 모듈이 사용자 및 암호를 저장하는 위치와 방법에 상관하지 않음을 보여줍니다.
Perl의 프로토 타입에 대한 경고 용 +1 – tadmc
프로토 타입은 메서드 호출에서 완전히 무시됩니다 (잘못된 프로토 타입을 눈치 채지 못한 이유입니다). – cjm