2014-11-21 10 views
0

깊게 중첩 된 구조 인 해시가 있습니다. 중첩 수준은 사전에 알 수 없습니다. 그러나 각 수준에는 두 개의 속성 "인스턴스"와 "종속성"의 또 다른 해시가 있습니다. 그래서 일종의 재귀적인 해시입니다.Perl : 서브 루틴에서 hashref를 반환합니다.

my $HASH = { 
    "top"=> { 
     "instance" => "top_instance", 
     "dependencies" => { 
      "sub_block1" => { 
       "instance" => "sub_block1_instance", 
       "dependencies" => {} 
      }, 
      "sub_block2" => { 
       "instance" => "sub_block2_instance", 
       "dependencies" => { 
        "sub_block3" => { 
         "instance" => "sub_block3_instance", 
         "dependencies" => {} 
        } 
       } 
      } 
     } 
    } 
}; 

나는 사용자 정의 문자열을 받아들이고 지정된 계층 구조에서 해시의 내부 부분을 반환하는 서브 루틴을 가지고 있습니다.

사용자가 "sub_block2"를 지정하는 경우

예, 서브 루틴이 해시 반환해야합니다 : 당신이 볼 수 있듯이,이 재귀가

sub get_starting_point { 
    my $string = shift; 
    my $config = shift; 
    foreach my $key (keys %$config) { 
     if($key ne $string) { 
      # if current key is not what user asked for, recurse into next level of hierarchy 
      if (exists $$config{$key}{dependencies}) { 
       &get_starting_point($$config{$key}{dependencies}); 
      } 
     } else { 
      # we found the key, return the hash under this hierarchy 
      my $tempHash = {$key => $$config{$key}}; 
      print ref($tempHash); # correctly prints HASH 
      print Dumper($tempHash); # correctly prints out the sub-hash 
      return $tempHash; # I am expecting this return value to be a hash-ref 
     } 
    } 
} 

입니다 : 이것은 내 서브 루틴이

{ 
    "sub_block2" => { 
     "instance" => "sub_block2_instance", 
     "dependencies" => { 
      "sub_block3" => { 
       "instance" => "sub_block3_instance", 
       "dependencies" => {} 
      } 
     } 
    } 
} 

입니다 함수는 인수와 일치하는 키를 치고 해당 키 아래의 완전한 하위 해시를 반환 할 때까지 해시를 깊이있게 유지합니다.

이렇게하면이 서브 루틴을 호출합니다.

my $subHash = get_starting_point("sub_block2",$HASH); 
print ref($subHash); # is not a ref 
print Dumper($subHash); # prints nothing 

내가 뭘 잘못하고있어!?!?

편집 : 내 정확한 문제로 질문을 업데이트했습니다. 기대했던대로 일하기 전에 사용했던 간단한 예처럼 보입니다.

+1

표시된 코드에 아무 문제가 없습니다. 복사 및 붙여 넣기, 가져 오기 추가, C 스타일 주석 제거 (perl 주석 사용) # 예상대로 인쇄되었습니다. 정확한 코드를 보여줄 수 있습니까? 엄격한 경고를 사용하고 있습니까? – Nate

+0

hashref를 * 사용하려고 할 때 문제가 발생했다고 생각합니다. 당신이 시도하고있는 것을 보여주십시오. http://perlmonks.org?node=References+quick+reference에는 참조 번호 – ysth

답변

2

foreach가 평가하는 값을 리턴합니다 (하위의 마지막 명령문 인 덕분에). 참조가 아닌 것은 놀라운 일이 아닙니다.

&get_starting_point($$config{$key}{dependencies}); 

my $rv = get_starting_point($config->{$key}{dependencies}); 
return $rv if $rv; 

하고 오히려 거짓 뭔가를 반환하는 foreach 문에 의존하지 않고 마지막에 return undef;을 추가해야합니다.

sub get_starting_point { 
    my $string = shift; 
    my $config = shift; 
    for my $key (keys %$config) { 
     if ($key eq $string) { 
      return { $key => $config->{$key} }; 
     } 

     if ($config->{$key}{dependencies}) { 
      my $rv = get_starting_point($config->{$key}{dependencies}); 
      return $rv if $rv; 
     } 
    } 

    return undef; 
} 

참고 :

  • &를 사용하여 하위 호출을 접두사하지 마십시오. 그게 뭔지 알기라도 해?
  • 대부분 사람들은 $$config{$key}보다 더 읽기 쉬운 $config->{$key}을 찾습니다.
+0

Perfect를 사용하는 방법을 이해하는 데 유용한 규칙이 있습니다. 나는 그 재림이 문제라는 것을 깨달았다. 그러나 실제로 서브 루틴에서 실행되는 마지막 명령문 인 foreach 루프에서 돌아 오는 것으로 생각하지 않았습니다. – shikhanshu

+0

도움을 주셔서 감사합니다! 서브 루틴 호출은 &는 무엇을 하는가? 나는 항상 그들을 사용했다. 더 자세한 설명을 얻으려면이 링크를 읽으십시오 : http://stackoverflow.com/questions/1347396/when-should-i-use-the-to-call-a-perl-subroutine 그리고 나는 더 이상 그것을 사용하지 않을 것입니다! – shikhanshu

+0

프로토 타입이 무시되도록합니다. – ikegami

0

아야. 재귀 함수에서 "return"문이 재귀를 즉시 중단하고 값을 반환한다고 가정합니다. 그렇지 않습니다. 재귀가 가능한 한 깊어지고 다시 돌아 오기 시작하면 더 이상 돌아갈 수있는 것이 없습니다.

전역 서브 루틴을 설정하여이를 해결했으며 서브 루틴 내에서이 전역을 하위 해시로 설정하기 만합니다.

그건 내 목적에 도움이됩니다!

+0

아, 나쁨. 세계에 대한 이유는 없습니다. – ikegami