2012-06-21 4 views
3

Data :: Dumper를 사용하여 Perl로 데이터를 직렬화했습니다. 이제 다른 프로그램에서 나는 eval를 사용하여 직렬화하기 위해 노력하고있어 나는군요 : 내 프로그램에 use warnings; use strict;을 사용하고

Global symbol "$VAR1" requires explicit package name 

.

my $wiki_categories = eval($db_row->{categories}); 
die [email protected] if [email protected]; 
/* use $wiki_categories */ 

가 어떻게 내 프로그램 my로 선언되지 않는 때문에 "$VAR1" 죽어 해제 할 수 있습니다 : 여기

내가 eval 코드를 보내고있어 어떻게?

eval$db_row->{categories} 앞에 "my "을 붙이시겠습니까? 이와 같이 :

my $wiki_categories = eval("my ".$db_row->{categories}); 

나는 아직 테스트하지 않았지만 효과가있을 것이라고 생각합니다.

다른 방법은 없나요? 아마 그것을 어떤 블록에 싸서, 그 블록을 엄격하게하지 않을 것인가? 나는 그것을 해본 적이 없지만 언급 한 것을 보았다.

도움을 주셨습니다.

+0

Data :: Dumper는 디버깅 도구입니다. 이 방법으로 사용하면 안됩니다. JSON이 더 나은 대안입니다. – ikegami

+0

이것은 후속 조치입니다. http://stackoverflow.com/questions/11092658/how-do-i-serialize-an-array-of-array-references-in-perl – daxim

+0

'my $ VAR1; eval ($ db_row -> {categories}); my $ wiki_categories = $ VAR1; '을 사용하여 오류를 제거하십시오. 그러나 이미있는 대답은 그보다 훨씬 더 도움이됩니다. 이를 읽고 데이터 저장을 위해 다른 모듈을 사용해보십시오. – simbabque

답변

8

이것은 정상입니다. 직렬화 데이터 :: 덤퍼를 사용하려면

$VAR1 = ...your data... 

, 당신은 그것을 조금을 구성해야합니다 : 데이터 :: 덤퍼 데이터를 직렬화 할 때 기본적으로, 그것은 뭔가를 출력합니다. Terse이 가장 중요한 설정 옵션 인 경우 $VAR 것을 끕니다.

use Data::Dumper; 

my $data = { 
    foo => 23, 
    bar => [qw(1 2 3)] 
}; 

my $dumper = Data::Dumper->new([]); 
$dumper->Terse(1); 

$dumper->Values([$data]); 
print $dumper->Dump; 

그런 다음 결과를 변수로 직접 평가할 수 있습니다.

my $data = eval $your_dump; 

당신은 데이터 : 덤퍼의 크기를 축소하기 위해 다양한 트릭을 할 수 있지만 전체에 효율적 빠르고 공간입니다. 주된 측면은 펄 (Perl)과 매우 불안정하다는 것입니다. 누구든지 덤프 파일을 수정할 수 있으면 프로그램을 소유합니다.

Data::Serializer과 같이 CPAN에 모듈이 있습니다.

6

귀하의 질문에 많은 영향이 있으므로 가능한 한 많은 내용을 설명하려고 노력하겠습니다.

먼저 Data :: Dumper에 대한 perldoc을 읽습니다. 사용자의 필요에 따라 $Data::Dumper::Terse = 1으로 설정하면 충분할 수 있습니다. 전역 변수에는 많은 옵션이 있으므로 지역화해야합니다. 그러나 이것은 소비자가 아니라 생산자를 데이터로 바꾼다. 당신이 얼마나 많은 통제력을 가지고 있는지 모르겠습니다. 귀하의 질문에 은 소비자가 노력하고 있지만 생산자에 대한 어떠한 통제도 언급하지 않았 음을 의미합니다. 어쩌면 데이터가 이미 존재하므로 그대로 사용해야합니다.

다음 의미는 당신이 Data :: Dumper에 묶여 있다는 것입니다. 다시 말하지만 데이터가 이미 존재할 수 있으므로 너무 좋지는 않습니다. 그렇지 않은 경우 다른 저장 가능한 형식으로 전환하는 것이 좋습니다. 요즘에는 JSON이 꽤 일반적입니다. JSON은 코어 펄의 일부는 아니지만 설치하는 것은 쉽지 않습니다. 또한 훨씬 쉽게 만들 수 있습니다.한 가지 장점은 데이터가 다른 언어에서도 유용하다는 것입니다. 또 다른 한가지는 eval STRING을 피하는 것인데, 이는 데이터가 유출 될 경우 소비자를 쉽게 손상시킬 수 있습니다.

다음 항목은 그대로 해결하는 방법입니다. 예를 들어, 데이터가있는 경우. 간단한 해결책은 당신이했던 것처럼 my를 추가하는 것입니다. 이것은 잘 작동합니다. 또 다른 방법은 $ VAR1을 제거하는 것입니다 : (my $dumped = $db_row->{categories}) =~ s/^\s*\$\w+\s*=\s*//;. 또 다른 하나는 "no warnings"권리를 평가판에 넣는 것입니다 : eval ("no warnings; no strict; " . $db_row->{categories});.

가능한 경우 개인적으로 개인적으로 JSON을 사용합니다.

+0

DD를 시리얼 라이저로 사용하는 경우 Purity = 1을 사용하려고하므로 Terse = 1을 배제합니다. – ikegami

2

귀하의 코드는 제외 서서 일하는 것이 $VAR1eval의 범위에 선언되지 않은되고 use strict 'vars'이 유효하기 때문에 eval이 실패합니다.

가능한 한 긴밀한 블록 내에서 구조를 사용 중지하려면이 문제를 해결하십시오. A do 블록은 이렇게합니다.

my $wiki_categories = do { 
    no strict 'vars'; 
    eval $db_row->{categories}; 
};