【问题标题】:Using a dynamically generated variable name in Perl's strict mode [duplicate]在 Perl 的严格模式下使用动态生成的变量名 [重复]
【发布时间】:2013-06-30 08:05:06
【问题描述】:

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

这就是我想做的:

# 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;

有没有办法在严格模式下做到这一点?在其他关于类似问题的帖子中,人们说散列是答案,但我似乎不太了解如何使用散列来做到这一点。 不用说,这是一个非常简单的例子。在实际代码中,有 115 个可能的字段名称,都是从数据库中提取的,内容不可预测。

【问题讨论】:

  • 几周前我尝试过,但无法使其在严格模式下工作。你在 PerlMonks 上试过这个问题吗?

标签: perl variables strict


【解决方案1】:

使用哈希来做到这一点:

商店:

$myHash{q3} = "ex. data 3";

检索:

$result = $myHash{q3};

这有很多好处,例如:

  • 满足“使用严格”;

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

  • 由于根据最后一点,字段名称是一个列表,如果需要,您可以对它们进行任何其他列表操作(mapgrep)等...

    • 例如,要仅获取字段名称为“q[1-5]”形式的值,您可以这样做:

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

      $hash_ref = $sth->fetchrow_hashref;
      

【讨论】:

    【解决方案2】:

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

    my @q = ("ex. data 1", ..., "ex. data 5");
    
    my $contents  = $q[ $some_index ];
    
    print $contents;
    

    $some_index 设置为所需的索引,因此无需动态名称。

    【讨论】:

      【解决方案3】:

      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;
      

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

      # 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;
      

      那里。没有乱七八糟的no strict,只有一个变量保存了你所有的数据。

      【讨论】:

      • 这似乎是要走的路。感谢您的回答!
      • 这可行,但请记住,严格不允许这样做是有原因的:这几乎总是一个非常糟糕的主意。
      • @user2543941 我们怎么强调都不为过:你会后悔使用符号引用。
      猜你喜欢
      • 2021-10-04
      • 2018-10-02
      • 2011-04-29
      • 1970-01-01
      • 2014-11-02
      • 2015-10-11
      • 2013-07-31
      • 1970-01-01
      相关资源
      最近更新 更多