2013-07-11 5 views
1

특정 인수를 생성자 유형에 전달하는 다양한 방법에 대해 다소 혼란 스럽습니다. 해시 참조 \%hash 또는 목록 foo => 1, bar => 1은 전달하지만 다른 하나는 croak이 전달됩니다 (예 : (single elements, array reference)).전달 된 생성자 인수가 해시 유형이 아닌 한 잘못된 인수가있는 경우?

예를 들어, 내 참조 또는 목록을 ... 통과 (This works for the way I do this)

my $obj = foo->new; 
my $data = $obj->dump(\%hash); 
my $data = $obj->dump(foo => 1, bar => 1); 

또는

패키지 모듈은
my $obj = foo->dump(\%hash); 
my $obj = foo->dump(foo => 1, bar => 1); 

:

package foo; 

use strict; 
use Carp; 

use Scalar::Util qw/reftype/; 

sub new { return bless {}, shift } 

sub dump { 
    my $class = shift; 
    my $self = shift; 
    unless (reftype($self) eq reftype {}) { 
     croak("Constructor method not a hash type!"); 
    } 
} 

1; 

나는 또한 조건부 사용에 대한 생각 했어 여기서 ? : 연산자를 사용하지만 오류가 제대로 발생하지 않습니다.

my $self = reftype($_[0]) eq reftype {} ? shift : {@_}; 

더 좋은 방법이 있습니까?

+0

여기서 'new()'가 호출되지 않는다는 것을 알고 계십니까? 그것은 당신의 질문과 직접적으로 관련이 없지만, 당신이 객체 지향 Perl 모듈'$ self'에서 변수를 호출하면, 명시 적 매개 변수 중 하나가 아니라'$ self'를 포함해야한다고 생각합니다. – innaM

+0

예, 방금 사용하거나 "my $ obj = foo-> new로 사용할 수있는 곳으로 만들었습니다. my $ data = $ obj-> dump (..)'그리고 당신은''$ self와 not one ... '을 정확히 의미합니까? – hwnd

답변

2

dump 메서드를 호출 할 수있는 다양한 방법을 살펴볼 수 있습니다.

"해시 목록"을 전달하면 요소 수는 (@_ % 2 == 0)이됩니다. 또한 하나 이상의 키 - 값 쌍이 있으면 첫 번째 인수 (키)는 문자열이므로 not defined reftype $_[0]이 성립합니다.

해시 참조를 전달하면 인수 목록에는이 참조 만 포함되어야하며 다른 값은 @_ == 1입니다. 첫 번째 인수는 해시입니다 : reftype($_[0]) eq 'HASH'. 이 축복하면 그냥 물어의 $invocant 클래스 이름 또는 객체 인 경우

sub dump { 
    my $invocant = shift; 
    my $hashref; 
    if (@_ == 1 and reftype $_[0] eq 'HASH') { 
    $hashref = $_[0]; 
    } elsif (@_ % 2 == 0 and (@_ == 0 or not defined reftype $_[0])) { 
    $hashref = +{ @_ }; 
    } else { 
    croak "Unknown argument format: either pass a hashref, or an even-valued list"; 
    } 
    ...; # do something with $hashref 
} 

밖으로 찾는 방법은 다음과 같습니다 : 그래서

하나가 뭔가를 할 수있는, 해시 참조 인수를 넣어

if (defined Scalar::Util::blessed $invocant) { 
    say "Yep, it is an object"; 
} else { 
    say "Nope, it is a package name"; 
} 
+0

왜'+ {@_} '에'+'가 사용됩니까? – hwnd

+1

이 경우'+'는 부적절합니다. (이것은 중괄호가 hashref를 형성한다는 것을 분명히하기 위해 고안 한 습관입니다. 이것은 mapref가 hashref를 반환 할 때만 중요합니다. 예를 들어'map + {@ $ _}, [1, 2] , [3, 4]'). – amon

+0

이 질문에 관련된 질문이 있습니다. 새 스레드를 게시하는 대신 채팅 할 수있는 방법이 있습니까? – hwnd

2

"해시 목록"과 같은 것은 없습니다. foo => 1, bar => 1은 단지 4 개의 요소 목록입니다. 해시 참조 및 심지어 수의 args를 허용하려는 것처럼 들립니다.

sub dump { 
    my $self = shift; 
    my %args; 
    if (@_ == 1) { 
     croak("...") if (ref($_[0]) // '') ne 'HASH'; 
     %args = %{ $_[0] }; 
    } else { 
     croak("...") if @_ % 2 != 0; 
     %args = @_; 
    } 

    ... 
} 
+0

예, 원래이 작업과 비슷한 작업을 수행했지만, 내가 빠진 작업을 확인했습니다. 의견을 보내 주셔서 감사합니다. – hwnd

+0

코드 라인과'..ne 'HASH';'와'ne ref {}'의 차이점은 무엇입니까? – hwnd

+0

'ref {}'는 잘 알려져 있고 상수 인 문자열'HASH'을 얻기 위해 불필요하게 두 변수를 생성하고 소멸시킵니다. – ikegami