2010-12-22 3 views
2

해시가 연결된 개체와 관련된 함수에 액세스 할 수 있도록 스크립트의 초기 단계 인 하위 루틴에 대해 "묶음"을 호출해야하는 내 스크립트에서 작은 문제가있는 것 같습니다. . 문제는 "Cbc_encrypt_test.pl 라인 30에서 unblessed reference에"SetWriteMode "메서드를 호출 할 수 없다는 오류를 반환하는 스크립트를 실행하려고 할 때입니다." 처음에 나는 그것이 무슨 말을하고 있는지 전혀 몰랐다. 문제는 내가 처음부터 해시 참조를 반환하는 서브 루틴을 가리키는 참조를 사용했기 때문이라고 생각한다. 왜냐하면 지금까지는 "config_file = \ % cfg"를 이해하고 있기 때문입니다. Perlref에 대해 perldoc을 본 후에 나는 아직도 길을 잃었다. 나는이 문서를 꽤 잘 읽고 내가 필요로하는 방식으로 서브 루틴을 참조하는 것에 대해서는 아무것도 보지 못했다.서브 루틴에 "묶어"사용하는 방법은 무엇입니까?

여기까지 전체 스크립트.

#!/usr/bin/perl 

use strict; 

use warnings; 

use Term::ANSIColor; 

use Config::IniFiles; 

use Crypt::CBC; 

start_script(); 



sub start_script { 

    system ("clear"); 

    encrypt_password(); 

} # end start_script 

sub config_file { 

    my $cfg_file = 'settings.ini'; 

    my %cfg; 

    tie %cfg, 'Config::IniFiles', (-file => "$cfg_file"); 

    return \%cfg; 

} # end config_file 

sub encrypt_password { 
    my $password = config_file()->{ESX}{password}; 
    my $cipher = Crypt::CBC->new(-key => 'EF1FAD9B87F8365B242669E624FEB36CDBCCFEE0096CC45DDDCF6F5995E83F61', 
        -cipher => 'Rijndael' 
        ); 
    my $encrypted_password = $cipher->encrypt_hex("$password"); 
    chomp $encrypted_password; 
    config_file()->{ESX}{password} = $encrypted_password; 
    tied config_file()->SetWriteMode(0666); 
    tied config_file()->RewriteConfig(); 
    return $encrypted_password; 
} # end encrypt_password 

답변

2

우선 순위 문제와 비슷합니다. B::Deparse을 통해 구조를 실행하면 문제를 보여줍니다

$ perl -MO=Deparse,-p -e 'tied config_file()->method()' 
tied(config_file()->method); 
-e syntax OK 

그래서 펄이 처음 config_file()에 의해 반환 된 참조에 메소드를 호출하는 시도를하고, 그 기준은 축복받은 목적이 아니기 때문에 실패 (같은 tied는 반환). 대신

시도 : 더 나은 아직

tied(%{config_file()})->SetWriteMode(0666); 
tied(%{config_file()})->RewriteConfig(); 

또는 :

my $cfg = tied %{config_file()}; 
$cfg->SetWriteMode(0666); 
$cfg->RewriteConfig(); 

또는

또한
for (tied %{config_file()}) { 
    $_->SetWriteMode(0666); 
    $_->RewriteConfig(); 
} 

Config::IniFiles 기록 된 방법에 따라, 당신은 문제가 실행할 수 있습니다, 여기서 각 호출을 ~ config_file()에 새 개체가 반환되므로 집계 호출이 적용되지 않습니다. 서로 적절하게 my answer to your previous question과 같이 개체를 캐시해야합니다.

편집 : ysth가 지적한 누락 된 참조가 두 번째 문제점이었을 것이라고 나는 생각하지 않았습니다. 위에 고정.

+0

B :: Deparse 란 무엇입니까? CPAN 모듈? – ianc1215

+0

'B :: Deparse'는 이미 설치 한 핵심 모듈입니다. 위의 사용법에서 Perl은'-e' 줄을 취하여 컴파일 한 다음 op-tree를 Perl 소스 코드로 다시 변환하는'B :: Deparse'에 컴파일 된 op-tree를 전달합니다. '-p' 옵션은 암묵적으로 괄호를 삽입하도록 deparse에 지시합니다. –

+0

다른 질문에서 캐싱에 관한 부분을 놓쳐 버렸을 것입니다. 위의 솔루션은 작동하지만 지금은 설정 모듈이 실제로 비밀번호를 쓰지 않고 있다는 사실을 알게되어서 나보다 앞서 즐거움을 얻습니다. – ianc1215

4

묶인 변수에 묶음을 사용해야합니다. 당신이 이러한 변수에 대한 참조가있는 경우, 당신은이 작업을 수행 할 수 있습니다

tied(%{ config_file() }) 

하지만 코드가 약자로, 각각의 호출은 새로운 묶여 해시를 생성합니다 CONFIG_FILE, 및 방법에

당신은 이전 해시의 호출했다 묶인 객체는 좋지 않을 것이므로 config_file()이 한 번만 호출되도록 (또는 내부적으로 결과를 메모하도록)해야합니다.

+0

+1, 우선 순위 문제에 중점을두고 누락 된 역 참조를 바로 살펴 보았습니다. –

관련 문제