Perl에서 해시(연관 배열)는 키-값 쌍을 저장하는 강력한 도구입니다. 하지만 이들을 사용할 때는 특히 구조를 동시에 반복하고 수정할 때 주의가 필요합니다. 여기서 놓친 세부사항들은 진단하기 어려운 오류를 초래할 수 있습니다.
연관 배열은 Perl의 초기 버전(Perl 1/2)에서 도입되어, 핵심 수준에서 해시에 대한 완전한 지원을 제공하는 최초의 언어 중 하나가 되었습니다. 시간이 지나면서 반복(each), 삭제(delete), 대량 변환(map, grep), 그리고 탐색 중 크기/내용 변경에 대한 추가적인 기능들이 생겼습니다.
해시를 반복하면서 동시에 내용을 수정하는 것은, 특히 요소를 삭제할 때 예기치 않은 효과를 초래할 수 있습니다: 요소를 пропустить, 같은 키를 다시 반복, 또는 심지어 무한 루프에 빠질 수도 있습니다. 또한 키 순서는 보장되지 않으며 Perl 버전 간에 변경될 수 있습니다.
each를 사용할 때는 반복 중에 해시를 변경하지 마세요. 내부 커서가 잘못될 수 있습니다.keys를 통해 키 목록을 수집한 후, 별도의 루프에서 이를 반복하면서 삭제하세요.while (my ($k, $v) = each %h)를 사용하되, 루프 내에서 delete와 합쳐서 사용하지 마세요. 예기치 않은 결과를 피할 수 있습니다.요소를 올바르게 삭제하는 예:
my %h = (a=>1, b=>2, c=>3); for my $k (keys %h) { delete $h{$k} if $h{$k} == 2; }
잘못된 접근의 예:
while (my ($k, $v) = each %h) { delete $h{$k}; # 이는 키를 пропустить할 수 있습니다. }
주요 특징:
while (each %h) 루프 내에서 해시의 요소를 안전하게 삭제할 수 있나요?
아니요, 이는 내부 반복 커서가 리셋되어 해시의 일부를 놓칠 수 있습니다.
요소를 삭제한 후 키의 순서에는 어떤 일이 발생하나요?
순서는 보장되지 않으며 변경될 수 있습니다. 또한 동일한 Perl을 사용하는 프로그램 간에 탐색 순서가 다를 수 있습니다.
each를 통해 반복하는 동안 해시 요소의 값을 변경할 수 있나요?
네, 값(구조는 아니지만)을 변경하는 것은 안전합니다.
예:
while (my ($k, $v) = each %h) { $h{$k} = $v + 10; }
각각의 루프 내에서 요소를 삭제하는 경우:
my %h = (a=>1, b=>2, c=>3); while (my ($k, $v) = each %h) { delete $h{$k} if $v == 1; }
장점:
단점:
삭제를 위한 키 목록 생성:
my %h = (a=>1, b=>2, c=>3); for my $k (keys %h) { delete $h{$k} if $h{$k} == 1; }
장점:
단점: