2010-02-16 2 views
7

Perl에서 문자열을 기반으로 전역 변수를 만들 수 있습니까?문자열을 기반으로 Perl 변수 이름을 만들려면 어떻게해야합니까?

예를 들어, 내가 같은 함수가 있다면 :

sub create_glob_var { 
    my ($glob_var_str) = @_; 
    # something like this (but not a hash access). 
    our ${$glob_var_str}; 
}; 

을 나는 전화가 좋아 :

create_glob_var("bar"); 

어떻게 실제로 $bar라는 전역 변수를 만들 수 create_glob_var을 수정할 수 있을까?

내 프로젝트에서 펄 5.8.5를 사용 중입니다.

편집

다음은 작동하지 않습니다

use strict; 
BEGIN { 
    sub create_glob_var { 
    my ($glob_var_str) = @_; 
    no strict 'refs'; 
    $$glob_var_str = undef; # or whatever you want to set it to 
    } 

    create_glob_var("bah"); 
}; 

$bah = "blah"; 

는 생산 :

Variable "$bah" is not imported at /nfs/pdx/home/rbroger1/tmp2.pl line 12. 
Global symbol "$bah" requires explicit package name at /nfs/pdx/home/rbroger1/tmp2.pl line 12. 
Execution of /nfs/pdx/home/rbroger1/tmp2.pl aborted due to compilation errors.

참고 내가 전역 변수를 사용하여 ozone depletion and male pattern baldness 원인이 있음을 알고 있습니다. 이미 전역 변수를 사용하여 완전히 감염된 일부 레거시 코드를 정리하려고합니다. 한 번에 하나의 리팩터 ...

+0

서브 루틴은 전역 변수를 생성하지만 여전히 1) $ My :: Package :: bah = "blah"중 하나의 엄격한 방법으로 액세스해야합니다. 2) vars qw ($ bah); $ bah = "blah"또는 3) 우리의 $ bah = "blah". – Sean

+4

이런 일은하지 마십시오. http://stackoverflow.com/questions/1549685/how-can-i-use-a-variable-as-a-variable-name-in-perl –

+0

동의. 새로운 스칼라를 생성하는 대신 글로벌 해시를 사용하여 데이터를 저장하십시오 (전역 전역을 사용해야하는 경우). – Ether

답변

5

요하는 경우 당신은 오래된 코드를 정리하려고하는데 필요한 변수를 내보내는 모듈을 작성할 수 있습니다. create_glob_var을 호출 할 필요가있을 때마다이 패키지에 변수를 추가하고 가져 오기 목록에 넣으십시오.

이렇게하면 진행 상황과 변수 사용 방법을 추적하는 데 도움이됩니다.

package MyVars; 

use strict; use warnings; 

use Exporter 'import'; 

our($x, %y, @z); 

our @EXPORT_OK = qw($x %y @z); 

스크립트 :

#!/usr/bin/perl 

use strict;use warnings; 

use MyVars qw($x %y @z); 

$x = 'test'; 
%y = (a => 1, b => 2); 
@z = qw(a b c); 

use Data::Dumper; 
print Dumper \($x, %y, @z); 

출력 : 신안 Ünür에 의해

$VAR1 = \'test'; 
$VAR2 = { 
      'a' => 1, 
      'b' => 2 
     }; 
$VAR3 = [ 
      'a', 
      'b', 
      'c' 
     ];
2

eval을 사용해야하지만 일반적으로 악으로 간주됩니다. 같은 뭔가 :

eval("$glob_var_str = \@_;");

편집

그냥 당신은 단지 my없이 no strict refs하여이 작업을 수행 할 수 있음을 확인했습니다.

+2

거짓말. '엄격한 심판이 아니다 '. – fennec

+0

'use strict' 또는 without with? –

+0

eval은 그것을 할 수는 있지만 한 가지 이상의 방법이 있습니다 ... eval을 사용할 필요가 없습니다. – Paul

2

이 질문을보고하십시오 : 간단히 Does Perl have PHP-like dynamic variables?

, 당신이, use strict이 유효 필요한 경우에만 $$glob_var_str = "whatever";

+0

먼저 블록에 '엄격한 참조 없음'을 지정해야합니다. (당신이 엄격해야하기 때문에!) – fennec

3
sub create_glob_var { 
    my ($glob_var_str) = @_; 
    no strict 'refs'; 
    $$glob_var_str = undef; # or whatever you want to set it to 
} 

no strict 'refs'은 할 수있을 것 같아 항상하는 그것을 해야한다.

부록 :

서브 루틴을 작성하는 방법이 경우에 당신이 묻는 경우 create_glob_var 그런 다음 코드가 성공할 것 :

use strict; 
create_glob_var("bar"); 
$bar = "whatever"; 

... 그 대답은 "아니오"입니다

use strict; 
use vars qw($bar); 
$bar = "whatever"; 

을하지만이 펄 코딩 이전 스타일의 종류 : 그러나, 펄의 vars pragma는 당신이 원하는 것을 할 것입니다.요즘, 하나는 일반적으로 이런 짓을 했을까 :

use strict; 
our $bar = "blah"; 

our 또한 단지 자유롭게 나중에 사용할 수있는 전역 변수를 선언 할 수

our ($foo, @bar, %baz); 
# ... 
$foo = 5; 
@bar = (1, 2, 3); 
%baz = (this => 'that'); 
+0

답변 주셔서 감사합니다. 그것은 작동하지 않는 것 같습니다. ''엄격한''은 컴파일 (?) 시간에 불평하고있다. 내 업데이트 된 게시물을 참조하십시오. –

2

vars 프라그 이미 당신이 원하는에 대한 무거운 않기 때문에, 작업을 넣어 :

#! /usr/bin/perl 

use warnings; 
use strict; 
use vars; 

BEGIN { vars->import(qw/ $bah /) } 

$bah = "blah"; 
print $bah, "\n"; 

당신이 그것을 create_glob_var 철자를 선호하는 경우, 다음

를 사용 16,
#! /usr/bin/perl 

use warnings; 
use strict; 
use vars; 

sub create_glob_var { vars->import("\$$_[0]") } 

BEGIN { create_glob_var "bah" } 

$bah = "blah"; 
print $bah, "\n"; 

어느 쪽이든은, 출력은 our 이러한 변수를 선언하기보다는 이런 식으로하고 싶은 이유를 알고 싶소

blah

입니다. 예, 모든 것을 잡는 데는 몇 차례의 반복이 필요할 수 있지만, 어쨌든 단기 수정입니다. 맞습니까?

는 일반적으로, 당신은 변수 이름 ("Symbolic references" in perlref 참조)과 같은 변수를 사용할 수 있습니다,하지만 당신은 정말, 정말, 정말은 그렇게하고 싶지 않아 다음 strict 'refs' 프라그를 활성화하면이 기능을 사용할 수 없습니다. 그가 쓴

라파엘 가르시아 - 레즈는 큰 지혜를 보여 주었다 "나는 원래 문제가 무엇인지 모르겠지만, 해시를 사용하는 것이 좋습니다."

항목 :

+0

이 모든 작업을 수행하는 이유는 커스텀 명령 행 파서를 작성함으로써 누군가를 다시 발명 한 것입니다. 모든 툴 스택에서 사용됩니다. 불행하게도, 옵션을 선언하는 현재의 방법은 3000 줄의 코드에 3 개의 코드 섹션을 수정하는 것입니다. 그것은 정말로 소름 끼치게하고, 그것을 격렬히 위반한다 D.R.Y. 모든 코드를 10 줄 미만의 연속 코드로 만드는 데 필요한 모든 코드를 수집하여 전체 코드베이스에서 반복해야 할 필요성을 줄이려고합니다. –

+0

@Ross 위의 코드가 원하는 것을 수행하지 못합니까? –

1

대답은 참으로 최고입니다. 그러나 이것은 호기심을 불러 일으키기 때문에 약간의 독서 (perldoc perlmod)를 수행하고 패키지의 네임 스페이스에 액세스하는 방법으로 "package_name ::"해시에 대해 알게되었습니다.

다음 코드는 메인 :: 패키지의 심볼 테이블에 레코드를 추가

use strict; 
my $name = "blah"; 
my $var = "sss"; 
$main::{$name} = \$var; 

print "$main::blah\n"; 

이 인쇄 "SSS을".

그러나 "use strict"가 여전히 바보가 아니기 때문에 print 문에 패키지 이름을 추가해야했습니다.나는 계속 볼 것입니다 - 사용 vars는 현재 작동하지 않는 것 같습니다.

관련 문제