2014-09-08 5 views
-1

나는 SDBM_File 모듈을 사용하는 Perl 연결 해시를 가지고 있으며 값을 저장하거나 가져올 때 일부 문자 인코딩 변환을 수행해야합니다.filter_fetch_key에 대해 perldbmfilter를 사용하여 묶인 해시 반복자에 대한 무한 재귀

나는 documentation of perldbmfilter을 따라 갔고 일반적으로 제대로 작동하는 것으로 보입니다 : 예상대로 올바르게 인코딩 된 해시 결과를 얻었습니다. 인코딩에 대한 바이트 값을 파일에 저장합니다.이 값은 16 진수 편집기를 사용하여 확인합니다.

keys 또는 each 또는 Data::Dumper과 같은 해시 요소 또는 다른 해시에 대한 간단한 복사 작업을 사용하여 모든 해시 요소에 대한 반복 작업이 효과가 없습니다.

항상 얻는 것은 무한 재귀입니다. iterator가 끝까지 도달하지 못하는 것처럼 보입니다. 그리고 each을 사용하고 iterated 값을 인쇄하면 반복됩니다.

filter_fetch_key의 사용으로 문제점을 찾아 내고 거기에서 수행하는 charset 변환을 수행합니다. filter_fetch_key을 주석 처리하거나 필터 방법을 return shift으로 변경하면 반복이 다시 작동합니다. 이 중 하나는 내 문제를 해결하지만 호출자가 올바르게 인코딩 된 문자열을 보내려면 filter_fetch_key을 사용해야합니다.

$dbm->filter_fetch_key (sub { $_ = $self->_normalizeCharset($_); }); 

sub _normalizeCharset 
{ 
    my $self = shift || Carp::croak(...); 

    #return shift; 
    return ...::windows2utf(shift); 
} 

return shift의 주석을 제거하면 반복이 수행됩니다. 하지만 위와 같이 주석을 달았습니다. 나는 그것이 $_에 일어나는 일을 할 것이라고 생각하지만, windows2utf은 주어진 데이터를 복사하고 일부 문자 인코딩을하기 때문에 나는 전혀 모른다. 키와 값을 저장하고 값을 가져 오는 경우에도 동일한 방식으로 작동합니다. 유일한 키는 문제이며, 반복 할 경우에만, 특정 키를 직접 요청하지 않아야합니다.

내가 잘못하고있는 것에 대한 힌트가 있습니까?

Perlmonks에 스레드가 있습니다.

+0

http://www.perlmonks.org/?node_id=1099905 – choroba

+0

코드를 좀 더 살펴 보는 것이 좋을 것입니다. '$ dbm'이란 무엇입니까? 상응하는'filter_store_key'를 가지고 있습니까? '... :: windows2utf' 란 무엇입니까? – Borodin

+0

정규화를 수행하는 방법을 사용한 이유가 표시되지 않습니다. 당신의 필터는'sub {$ _ = _normalizeCharset (undef, $ _)}'또는 심지어'sub {$ _ = ... :: windows2utf (shift)} '일 수도 있습니다. 그러나 나는 그 신비한' ... :: windows2utf'일지도 모릅니다. – Borodin

답변

1

나는 테스트 동안 filter_fetch_key이 키 값 undef을 사용하여 한 번만 내 함수를 호출하고이 함수는 편의상 빈 문자열을 반환한다는 것을 알아 냈습니다. 이것은 무한 루프를 일으키는 것 같아요. 누군가가 그 빈 문자열을 어떤 이유로 해시에 대한 새로운 키로 추가하려고하고, 무효화되는 일부 반복자에 문제가 생길 수 있습니다. 그 재미있는 점은 키의 변경이 완벽해야한다는 것입니다. 설명서의 예제 중 하나가 정확하게 나와 있기 때문에 내 테스트에서 undef을 제외한 각 키를 바꿀 수 있다는 것을 보여 주므로 내가 좋아하는 부분을 완전히 만들 수 있습니다. 예를 들어 __를 앞에 붙이면 새 키가 생성됩니다. 문제가되지 않습니다. 반환하지 않는 경우에만 undefundef 무한 루프가 발생합니다. 다음 방법의 첫 번째 버전은 작동하지만 두 번째 버전은 작동하지 않습니다.

sub _normalizeCharset 
{ 
    my $self = shift || Carp::croak(...); 
    my $value = shift; 
    my $key = shift || 0; 
return undef unless (defined($value)); 
#return '' unless (defined($value)); 

$value = "__$value" if ($key); 

    return ...::windows2utf($value); 
} 


sub _normalizeCharset 
{ 
    my $self = shift || Carp::croak(...); 
    my $value = shift; 
    my $key = shift || 0; 
#return undef unless (defined($value)); 
return '' unless (defined($value)); 

$value = "__$value" if ($key); 

    return ...::windows2utf($value); 
} 

나는 undef이 반복 키 또는의 끝을 나타내는 필터의 특별한 신호가 될 수 있으며, 단순히 일반 해시 키로 의미하지 않는다 같아요. 적어도 나는 그것을 어디에도 두지 않는다.