散列格式字符串的插值

时间:2016-05-06 20:06:58

标签: perl hash interpolation string-interpolation

我正在研究perl cgi脚本。 它应该处理某种类型的数据库,其中打印布局和要打印的值存储在散列中。这是我的代码片段:

    my $va=1;
    my $vb=2;
    my $fa="";
    my $fb="";
    my %h=( 'format' => { 'a' => "This is the value of variable \$va: $va",
                          'b' => "This is the value of variable \$vb: $vb"
                        },
            'values' => { 'a' => "value A",
                          'b' => "value B"
                        }
          );
    $fa=$h{'format'}->{'a'};
    $fb=$h{'format'}->{'b'};
    $va=$h{'values'}->{'a'};
    $vb=$h{'values'}->{'b'};
    print "$fa<br/>\n";
    print "$fb<br/>\n";
    $va=3;
    $vb=4;
    print "$fa<br/>\n";
    print "$fb<br/>\n";

直到现在我才得到这个(错误的)打印输出:

   This is the value of variable $va: 1
   This is the value of variable $vb: 2
   This is the value of variable $va: 1
   This is the value of variable $vb: 2

我的期望是:

   This is the value of variable $va: value A
   This is the value of variable $vb: value B
   This is the value of variable $va: 3
   This is the value of variable $vb: 4

存储在散列中的格式字符串插值不起作用的原因是什么?

3 个答案:

答案 0 :(得分:2)

要延迟插值,最简单的方法是使用匿名子:

    my $va=1;
    my $vb=2;
    my $fa="";
    my $fb="";
    my %h=( 'format' => { 'a' => sub { "This is the value of variable \$va: $va" },
                          'b' => sub { "This is the value of variable \$vb: $vb" },
                        },
            'values' => { 'a' => "value A",
                          'b' => "value B",
                        }
          );
    $fa=$h{'format'}->{'a'};
    $fb=$h{'format'}->{'b'};
    $va=$h{'values'}->{'a'};
    $vb=$h{'values'}->{'b'};
    print $fa->() . "<br/>\n";
    print $fb->() . "<br/>\n";
    $va=3;
    $vb=4;
    print $fa->() . "<br/>\n";
    print $fb->() . "<br/>\n";

也就是说,使用模板系统。

答案 1 :(得分:1)

由于@ThisSuitIsBlack尚未注意到,这可能是我的XY问题。也许[s]printf可能对您有所帮助:

my %h=( 'format' => { 'a' => "This is the value of variable \$va: %s",
                      'b' => "This is the value of variable \$vb: %s"
                    },
        'values' => { 'a' => "value A",
                      'b' => "value B"
                    }
      );

printf( $h{format}{a}, $h{values}{a} );

这相当于

printf( "This is the value of variable \$va: %s", 'value A' );

给出了:

This is the value of variable $va: value A

答案 2 :(得分:0)

我在http://www.perlmonks.org/?node_id=408346

找到了解决方案

字符串必须重新引用&#39;:

    sub quote { qq!"$_[0]"! } # Use something more sophisticated which escapes properly.

    my $va=1;
    my $vb=2;
    my $fa="";
    my $fb="";

    my %h=( 'format' => { 'a' => 'This is the value of variable \$va: ${va}',
                          'b' => 'This is the value of variable \$vb: ${vb}'
                        },
            'values' => { 'a' => 'value A',
                          'b' => 'value B'
                        }
          );
    $fa=$h{'format'}->{'a'};
    $fb=$h{'format'}->{'b'};
    $va=$h{'values'}->{'a'};
    $vb=$h{'values'}->{'b'};
    print eval(quote($fa))."<br/>\n";
    print eval(quote($fb))."<br/>\n";
    $va=3;
    $vb=4;
    print eval(quote($fa))."<br/>\n";
    print eval(quote($fb))."<br/>\n";

现在打印输出就像想要的那样:

    This is the value of variable $va: value A
    This is the value of variable $vb: value B
    This is the value of variable $va: 3
    This is the value of variable $vb: 4

欢呼声。