2017-09-14 10 views
1

2 개 매개 변수를 허용하도록 정의 서브 루틴에 전달다음과 같이 나는 새로운 객체를 생성하고 펄

sub new { 
    my ($pkg, $input) = @_; 
    my $obj = {}; 
    bless ($obj, ref($pkg)||$pkg); 
    $obj->{key} = $input->{key}; 
} 

해시가 new에 인수로 전달 되었기 때문에 읽은 것으로부터 2 요소 배열로 표시됩니다. 따라서 pkgkey이어야하며 inputabc이어야합니다. 그러면 키를 보유하려면 어떻게해야합니까? $input->{key}은 무엇을 의미합니까?

답변

6

첫째,

my $new_obj = new P_module({ key => 'abc' }); 

더 나은이

my %anon = (key => 'abc'); 
my $new_obj = P_module->new(\%anon); 

에 대한 짧은

my $new_obj = P_module->new({ key => 'abc' }); 

로 작성

메소드 호출을 할 때, 호출자 (->의 왼쪽)가 첫 번째 인수로 전달됩니다.즉, $pkgP_module 문자열이고 $input{ key => 'abc' }이 반환 한 참조입니다.

$input은 해시에 대한 참조이므로 은 참조 된 해시에서 key 키가있는 요소의 값을 가져옵니다.


내가 쓴 것입니다 방법이 : 발신자의 해시에 대한 필요가 없습니다, 그리고 $existing_obj->new을 지원하는 이유가 없습니다

sub new { 
    my ($class, %args) = @_; 
    my $self = bless({}, $class);  # If base class. 
    #my $self = $class->SUPER::new(); # If inheriting. 
    $self->{key} = $args{$key}; 
    return $self; 
} 

my $obj = P_module->new(key => 'abc'); 

. 또한 표준 이름 인 $class$self을 사용합니다. 대신이의

bless ($obj, ref($pkg)||$pkg); 

:

+0

대단히 감사합니다. 그것은 매우 도움이 된 설명이었습니다 :) –

0

주변의 중괄호는 참조 또는 하나의 스칼라 인 hashref를 만듭니다. 인수 값은 제공된 해시 코드 $input->{key}"key"와 연관된 값에 액세스

-"P_module"

  • $input — 참조 가능성

    • $pkg — 포함하는 패키지의 이름 것 발신자가 제공 한 번호

      my $new_obj = new P_module({key => 'abc'}); 
      

      그것은 당신이

      my $new_obj = P_module->new({key => 'abc', other => 'unused'}); 
      

      "key"과 관련된 값이

      와 객체 ’의 상태로 복사됩니다 같은 다른 키를 추가 할 수 있습니다

      my $new_obj = P_module->new({key => 'abc'}); 
      

      로이 쓰기 더 나은 스타일 간주됩니다

      $obj->{key} = $input->{key}; 
      

      Perl 서브 루틴은 마지막 표현식의 값을 반환하므로 사용자의 대구 e에는 버그가 있습니다. 당신은 그 다음 다른 방법 예를 들어, 전화를 사용할 수있는 축복 객체를 반환하기 때문에 P_module::new의 마지막 줄

      bless ($obj, ref($pkg)||$pkg); 
      

      되고 싶어요, 모든

      my $new_obj = new P_module({key => 'abc'}); 
      print $new_obj->other_method_that_you_must_define(), "\n"; 
      
  • +0

    나는 그것을 고려하지 않았다. 내가 설명 할 수없는 코드 만 게시했습니다. 오류를 지적 주셔서 감사합니다. –

    2

    당신이이 이유가 있습니까?

    bless ($obj, $pkg); 
    

    없는 경우에, 나는 당신이 & 어딘가 다른 코드에서 붙여 잘라 있으리라 믿고있어. 당신이 원하는 것은 후자입니다. ref($pkg)||$pkg 허용

    당신은이 작업을 수행합니다 :

    my $new_object = $existing_obj->new; 
    

    대신

    my $new_object = new Classname; 
    

    을 당신은 아마 그럼 그냥 스틱, 그렇게 할 필요가 없기 때문에

    bless ($obj, $pkg); 
    
    +1

    동의합니다. '$ existing_obj-> new'가 필요했던 경우에는 여전히'ref ($ existing_obj) -> new'를 사용할 수 있습니다. 이 경우 (그리고 복제가 필요한 경우 별도의 '복제'생성자) 나는 훨씬 더 깨끗합니다. 즉,이 대답은 정말로 논평이며, 나는 그것을 그러한 것으로 표시 할 것입니다. – ikegami

    +1

    코멘트 시스템이 자세한 설명을 위해 필요한 공백과 포맷을 허용한다면, 나는 주석을 작성했을 것이다. –

    0

    메서드를 호출하면 객체 자체가 장면 뒤에서 전달됩니다. 또는 하위가 bless을 사용하는 경우 생성자이며 클래스 이름이 대신 전달됩니다. 따라서 모든 메소드는 첫 번째 인수로 객체 또는 클래스 이름을 수신합니다. 나머지는 메소드에 명시 적으로 전달 된 인수입니다.

    해시 참조{...}을 전달하면 스칼라가됩니다. 따라서 $input에 할당되며, "quitely"전달 된 클래스 이름은 $pkg에 할당됩니다.

    해시 참조하면서 그 인터페이스의 생성자는 가장 통상적으로 단순히 최종 평가 문 리턴 반환되기 때문에 return 생략해도

    sub new { 
        my ($class, $input) = @_; 
        my $self = { %$input }; 
        return bless $self, $class; 
    } 
    

    로 기입된다. 마지막 두 줄은 단순히 return bless { %$input }, $class;으로 작성 될 수 있으며 (익명) hashref가 초기화되어 패키지 $class에 축복되어 반환됩니다.

    그러나 일반적으로 인수를 처리하려고합니다. 하나의 경우 이 클래스에서 지원하는 것과 일치하는지 확인해야하며 사용자가 전달한 키를 맹목적으로 특성에 할당하는 것이 아닙니다. 그런 다음 기본값을 제공하고 필요한 경우 값을 확인하십시오.

    이 초기화는 종종 별도의 서브 루틴으로 나뉩니다.new$self에서 갱신되도록 기준 코드를 통해 "백"을 기입 예

    sub new { 
        my ($class, $input) = @_; 
        my $self = {}; 
        bless $self, $class;  # $self is an object now 
        $self->_init($input);  # on which methods can be called 
        return $self; 
    } 
    
    sub _init { 
        my ($self, $args) = @_; 
        # Check arguments, work out defaults (etc), 
        # then assign to self as appropriate 
        %$self = %$args; 
    } 
    

    들어.

    는 "보통"으로 호출

    my $new_obj = P_module->new({key => 'abc', other => '...'}); 
    

    아닌 간접 new P_module 표기로 사용한다. 일반적으로 new이라고하는 생성자는 보통 bless 해시 참조를 제공하므로 (따라서 객체 대신 클래스 이름이 전달됨) 해당 패키지를 "인식"하여 객체입니다.

    문학 : perlmod (클래스는 패키지), 자습서 perlootut 및 참조 perlobj.

    Perl에 내장 된 객체 지향 시설에 익숙해지면, 내가 권장하는 바에 따르면이 모든 것을 (그리고 훨씬 더) 쉽게 할 수있는 많은 모듈이 있습니다.

    가장 먼저 추천하는 것은 매우 현대적인 Moose이며 그 경량 대응 물은 Moo입니다.

    +0

    'my $ self = my $ self = {% $ input}; – ikegami

    +0

    @ikegami 나는 더 컴팩트 한 방법을 보여 주면서 (필자는 정확히 입력 된 정확한 형식을 가졌음), 필자에게 이것의 기본 목적. 그러나 유혹을 불러 일으켰다. 편집 해 주셔서 감사합니다. – zdim