2016-07-29 4 views
1

이것은 매우 단순 할 수 있지만 한 시간 이상 노력하고 있습니다.Perl이 Foreach 루프 (배열 해시)에서 서브 루틴으로 해시 참조 전달

좋아 .. 여기에 $ 행이 정말 해시 내 코드는

@collection = [ 
{ 
      'name' => 'Flo', 
      'model' => '23423', 
      'type' => 'Associate', 
      'id' => '1-23928-2392', 
      'age' => '23', 
}, 
{ 
      'name' => 'Flo1', 
      'model' => '23424', 
      'type' => 'Associate2', 
      'id' => '1-23928-23922', 
      'age' => '25', 
}]; 

foreach my $row (@collection) { 
    $build_status = $self->build_config($row); 
} 

sub build_config { 
    my $self = shift; 
    my %collect_rows = @_; 
    #my %collect_rows = shift; 

    print Dumper %collect_rows; exit; 
    exit; 
} 

입니다. 내가 그것을 인쇄하지만 .. 그것은 다음과 같은 출력 (I가 덤퍼를 사용하고),

$VAR1 = 'HASH(0x20a1d68)'; 
+0

나는'@collection = (...)'이 아니라'@collection = (...)'을 가지고 있다고 생각한다. 그렇지 않으면'$ VAR1 = 'ARRAY (0x20a1d68)';'와 같은 것을 얻을 것이다. – ThisSuitIsBlackNot

+0

ha .. 그 차이점은 무엇입니까? (...)은 해시를위한 것이고 [...]는 배열을위한 것입니다. 내가 맞습니까? 왜냐하면 코드에서 @collection = [...]처럼 선언 되었기 때문입니다. – Raja

답변

5

당신은 해시와 배열에 혼란 참조가 있습니다. 해시와 배열이 모두 단순히 나열하기 때문이다

my %hash = (1 => 2, 3 => 4); 

(공상 목록,하지만 난 빗나가) : 해시가 선언되어

my @array = (1, 2, 3); 

:

배열

가 선언된다. []{}을 사용해야하는 유일한 경우는 목록에 포함 된 값을 사용하거나 두 목록 (아래 참조)의 참조를 만들고 싶을 때입니다. =>들이 같은 일을하지만, %h = (a, 1) 휴식 것, 그래서 왼쪽을 인용 특별한 (예. 지방) 쉼표, 그냥 것을

참고 %h = ("a", 1) 잘 작동하고 %h = (a => 1)도 있기 때문에 잘 작동 a이 인용됩니다.

배열 참조이 같은 선언 :

my $aref = [1, 2, 3]; 

이 ... 당신이 스칼라로 배열 참조를 둘 필요가 있습니다. 그렇지과 같이 그것을 할 경우

my @array = [1, 2, 3]; 

는 ... 기준은 사용자가 원하지는 @array의 첫 번째 요소, 푸시됩니다.

my $href = {a => 1, b => 2}; 

유일한 시간 [] 배열 (아닌 AREF)에 사용되는 당신이 요소를 사용하도록 사용할 때입니다 :

해시 참조는 다음과 같이 선언 $array[1];을. 마찬가지로 해시와 마찬가지로 참조가 아니라면 {}을 사용하여 키 값인 $hash{a}을 가져옵니다. 이제

, 당신의 문제를 해결하기 위해, 당신은 이러한 변화에 대한 참조를 계속 사용할 수 있습니다 :

use warnings; 
use strict; 

use Data::Dumper; 

# declare an array ref with a list of hrefs 

my $collection = [ 
    { 
     'name' => 'Flo', 
     ... 
    }, 
    { 
     'name' => 'Flo1', 
     ... 
    } 
]; 

# dereference $collection with the "circumfix" operator, @{} 
# ...note that $row will always be an href (see bottom of post) 

foreach my $row (@{ $collection }) { 
    my $build_status = build_config($row); 
    print Dumper $build_status; 
} 

sub build_config { 
    # shift, as we're only accepting a single param... 
    # the $row href 

    my $collect_rows = shift; 
    return $collect_rows; 
} 

... 또는 비 심판 사용하도록을 변경 :

my @collection = (
    { 
     'name' => 'Flo', 
     ... 
    }, 
    { 
     'name' => 'Flo1', 
     ... 
    } 
); 

foreach my $row (@collection) { 
    my $build_status = build_config($row); 

    # build_config() accepts a single href ($row) 
    # and in this case, returns an href as well 

    print Dumper $build_status; 
} 

sub build_config { 
    # we've been passed in a single href ($row) 

    my $row = shift; 

    # return an href as a scalar 

    return $row; 
} 

내가 쓴를 Perl 참고 자료에 대한 자습서는 guide to Perl references에 관심이있을 수 있습니다. perlreftut도 있습니다.

하나의 마지막 포인트 ... 해시는 실제로 해시 참조이기 때문에 배열 내부에 {}으로 선언됩니다.다차원 데이터의 경우 Perl의 최상위 구조 만 여러 값을 포함 할 수 있습니다. 밑에있는 모든 것은 하나의 스칼라 값이어야합니다. 따라서 해시 배열을 가질 수 있지만 기술적으로나 글자 그대로는 값이 다른 구조에 대한 포인터 (참조) 인 스칼라를 포함하는 배열입니다. 포인터/참조는 단일 값입니다.

+2

정말 멋진 ... 감사합니다! – Raja

+0

환영합니다. – stevieb

+0

이 질문의 일부가 아니기 때문에 도움이 되었기를 바랍니다. 제가 자세히 설명하지는 않겠지 만,이 말을 할 것입니다 ... 배열이나 해시를 전달할 때와 같이 데이터를 전달할 때 참조 할 때 선호되는 방법이 종종 있습니다. 주위를 돌면 포인터를 보내지 않고 perl이 구조체의 복사본을 만들어야합니다. 심판에서 작업 할 때 원래 구조로 작업합니다. 실제 변수를 보내려는 경우 복사본을 만들 필요가 있기 때문에 원본 구조가 필요한 작업에서 수정되지 않습니다. – stevieb