在Perl的严格模式下使用动态生成的变量名称

use*_*941 5 variables perl strict

基本上,我想获取动态生成的字符串中命名的变量的内容,但是在严格模式下完成此操作的所有努力都失败了.有几个关于类似问题的帖子,但似乎没有一个解决方案对我有用.

这就是我想要做的:

# Fields:
$q1 = "ex. data 1";
$q2 = "ex. data 2";
$q3 = "ex. data 3";
$q4 = "ex. data 4";
$q5 = "ex. data 5";

# retrieve the desired field name.  q1, q2, q3, q4, or q5.
$field_name = fetch_the_desired_field_name();

# fetch the contents of the named field.  ex. data 1, ex. data 2, etc.
$contents_of_desired_field = $$field_name;

print $contents_of_desired_field;
Run Code Online (Sandbox Code Playgroud)

有没有办法在严格模式下执行此操作?在关于类似问题的其他帖子中,人们说哈希是答案,但我似乎无法完全掌握如何使用哈希来做到这一点.不言而喻,这是一个非常简单的例子.在实际代码中,有115个可能的字段名称,都是从数据库中提取的,具有不可预测的内容.

DVK*_*DVK 12

要使用哈希执行此操作:

商店:

$myHash{q3} = "ex. data 3";
Run Code Online (Sandbox Code Playgroud)

检索:

$result = $myHash{q3};
Run Code Online (Sandbox Code Playgroud)

这有许多好处,例如:

  • 满足"严格使用";

  • 您可以通过循环遍历所有字段名称 keys %myHash

  • 由于字段名称是最后一个列表的列表,因此如果需要,您可以对它们执行任何其他列表操作(map,grep)等...

    • 例如,要仅获取字段名称为"q [1-5]"形式的值,您可以执行以下操作:

      @subset = @myHash{ grep m/q[1-5]/ keys %myHash }; # Use a slice @{} operator.
      
      Run Code Online (Sandbox Code Playgroud)
    • 大多数数据库API(例如DBI)都有调用,当从表中查询行时,这些调用将自动返回散列的这种确切格式(或者更确切地说是散列引用)

      $hash_ref = $sth->fetchrow_hashref;
      
      Run Code Online (Sandbox Code Playgroud)


amo*_*mon 7

您不想动态生成变量名称!相反,使用哈希或数组:

my @q = ("ex. data 1", ..., "ex. data 5");

my $contents  = $q[ $some_index ];

print $contents;
Run Code Online (Sandbox Code Playgroud)

$some_index被设定为所需的索引,从而消除任何需要进行动态的名称.


dar*_*rch 5

strict明确地不允许您使用所谓的"符号引用".你可以通过询问Perl获得许可来解决这个问题:

use strict;
use warnings;
use 5.10.0;

our $x = '5';
my $field_name = 'x';

my $contents;
{ # no strict is lexially scoped
    no strict 'refs';
    $contents = ${$field_name};
}

say $contents;
Run Code Online (Sandbox Code Playgroud)

请注意,引用的变量必须是动态的,而不是词法的,并且通常不鼓励这种做法.以下是使用哈希解决问题的方法,正确的数据类型:

# Fields:
my %data = (
    q1 => "ex. data 1",
    q2 => "ex. data 2",
    q3 => "ex. data 3",
    q4 => "ex. data 4",
    q5 => "ex. data 5",
);

# retrieve the desired field name.  q1, q2, q3, q4, or q5.
$field_name = fetch_the_desired_field_name();

# fetch the contents of the named field.  ex. data 1, ex. data 2, etc.
$contents_of_desired_field = $data{$field_name};

print $contents_of_desired_field;
Run Code Online (Sandbox Code Playgroud)

那里.没有杂乱no strict,只有一个变量保存所有数据.

  • 这是可行的,但请记住,严格不允许这样做是有原因的:这几乎总是一个非常糟糕的主意。 (2认同)
  • @ user2543941我们不能强调这一点:你会后悔使用符号引用. (2认同)