繁体   English   中英

如何根据字符串创建Perl变量名?

[英]How can I create a Perl variable name based on a string?

在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" );

我怎么能修改create_glob_var来实际创建一个名为$bar的全局变量?

我的项目使用的是perl 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.

注意我意识到使用全局变量会导致臭氧消耗和男性型秃发 我正在尝试清理一些已经完全被全局变量感染的遗留代码。 一次一个重构......

如果要尝试清理旧代码,可以编写一个导出所需变量的模块。 每当您觉得需要调用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);

输出:

$VAR1 = \'test';
$VAR2 = {
          'a' => 1,
          'b' => 2
        };
$VAR3 = [
          'a',
          'b',
          'c'
        ];
sub create_glob_var {
    my ($glob_var_str) = @_;
    no strict 'refs';
    $$glob_var_str = undef;  # or whatever you want to set it to
}

只有在use strict有效no strict 'refs'情况下才能use strict no strict 'refs' ,它始终应该是。

附录:

如果您正在询问是否有办法编写子例程create_glob_var ,以便以下代码成功:

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

......然后答案是“不” 但是,Perl的vars pragma会做你想要的:

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

但这是一种旧式的Perl编码。 如今,人们通常会这样做:

use strict;
our $bar = "blah";

our也可以声明可以在以后自由使用的全局变量:

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

你必须使用eval ,但这通常被认为是邪恶的。 就像是:

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

编辑

只是验证,你只能这样做没有my ,并no strict refs

试着看看这个问题: Perl是否有类似PHP的动态变量?

简而言之,似乎你应该能够做到$$glob_var_str = "whatever";

vars pragma已经完成了你想要的繁重工作,所以把它付诸实践:

#! /usr/bin/perl

use warnings;
use strict;
use vars;

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

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

如果您更喜欢将其拼写为create_glob_var ,请使用

#! /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";

无论哪种方式,输出都是

blah

我很想知道你为什么要这样做,而不是用our方式声明这些变量。 是的,它可能需要几次迭代才能捕获它们,但这些都是短期修复,对吧?

在一般情况下,你可以使用一个变量作为一个变量名(见在perlref“符号引用” ),但你真的,真的, 真的不想这样做:启用strict 'refs'编译禁用此功能。

Rafael Garcia-Suarez写道:“我不知道你原来的问题是什么,但我建议使用哈希。”

也可以看看:

SinanÜnür的回答确实是最好的。 然而,这引起了我的好奇心,所以我做了一些阅读(perldoc perlmod)并学习了“package_name ::”hash作为访问包名称空间的方法。

以下代码将记录添加到main :: package的符号表中:

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

print "$main::blah\n";

这打印“sss”。

但是,我不得不将包名添加到print语句中,因为“use strict”仍然没有被愚弄。 我会继续寻找 - 使用vars目前似乎不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM