在这里doc中插入常量的首选方法是什么?

时间:2013-04-03 16:43:13

标签: perl

我确信有几种方法可以在<>中插入值'bar'进行插值下面,但最简洁的方法是什么?为什么?

use constant FOO => 'bar';

my $msg = <<EOF;
Foo is currently <whatever goes here to expand FOO>
EOF

5 个答案:

答案 0 :(得分:12)

这里有两种文档:

  • <<'END',其行为大致类似于单引号字符串(但没有转义),
  • <<"END",也是<<END,其行为类似于双引号字符串。

要在双引号字符串中插值,请使用标量变量:

my $foo = "bar";
my $msg = "Foo is currently $foo\n";

或者使用arrayref插值技巧

use constant FOO => "bar";
my $msg = "Foo is currently @{[ FOO ]}\n";

您还可以定义模板语言以替换正确的值。根据您的问题域,这可能会或可能不会更好:

my %vars = (FOO => "bar");
my $template = <<'END';
Foo is currently %FOO%;
END

(my $msg = $template) =~ s{%(\w+)%}{$vars{$1} // die "Unknown variable $1"}eg;

答案 1 :(得分:9)

许多CPAN模块比use constant pragma更好地执行常量的问题是它们不是标准Perl包的一部分。不幸的是,在您可能不拥有的机器上下载CPAN模块非常困难。

因此,我刚刚决定坚持use constant,直到Perl开始包含类似Readonly的内容作为其标准模块的一部分(并且只有当像RedHat和Solaris这样的发行版决定更新到那些Perl的版本。我在生产服务器上仍然坚持使用5.8.8。)

幸运的是,如果你知道从黑客传递给黑客的神秘咒语,你可以插入用use constant定义的常量。

@{[...]}放在常量周围。这也适用于类中的方法:

use 5.12.0;
use constant {
    FOO => "This is my value of foo",
};

my $data =<<EOT;
this is my very long
value of my variable that
also happens to contain
the value of the constant
'FOO' which has the value
of @{[FOO]}
EOT

say $data;

输出:

this is my very long
value of my variable that
also happens to contain
the value of the constant
'FOO' which has the value
of This is my value of foo

使用方法:

say "The employee's name is @{[$employee->Name]}";

除了:

还有另一种使用常量的方法,我曾经在use constant出现之前使用过它。它是这样的:

*FOO = \"This is my value of foo";
our $FOO;

my $data =<<EOT;
this is my very long
value blah, blah, blah $FOO
EOT

say $data;

您可以将$FOO用作任何其他标量值,并且无法修改。您尝试修改该值,然后得到:

  

在......

尝试修改只读值

答案 2 :(得分:4)

使用Const::Fast代替Readonlyconstant。它们插入而没有任何扭曲。见CPAN modules for defining constants

  

对于条件编译,常量是一个不错的选择。它是一个成熟的模块,被广泛使用。

     

...

     

如果需要数组或散列常量或不可变的富数据结构,请使用Const :: Fast。它与Attribute :: Constant之间的竞争非常激烈,但Const :: Fast似乎更成熟,并且有更多的版本。

另一方面,您似乎正在编写自己的模板代码。别。相反,使用像HTML::Template这样简单的东西:

use HTML::Template;

use constant FOO => 'bar';

my $tmpl = HTML::Template->new(scalarref => \ <<EOF
Foo is currently <TMPL_VAR VALUE>
EOF
);

$tmpl->param(VALUE => FOO);
print $tmpl->output;

答案 3 :(得分:3)

您是否考虑过使用"read-only variables"作为常量? perlcritic在严重等级4(默认为5级)

中对其进行推荐
use Readonly;
Readonly my $FOO => 'bar';

my $msg = <<"EOF";
Foo is currently <$FOO>
EOF

P.S。 模块Const::Fast(受结节Readonly启发)似乎是更好的选择。

答案 4 :(得分:1)

晚会,但another version of the arrayref trick可以在标量上下文中执行此操作:${\FOO}。例子,在cygwin的perl 5.22.2中测试:

use constant FOO=>'bar';
print <<EOF
backslash -${\FOO}-
backslash and parens -${\(FOO)}-
EOF

产生

backslash -bar-
backslash and parens -bar-

感谢d-ash向我介绍了他在perlpp源预处理器heresee also this answer)中使用的这种技术。 (免责声明:我现在是perlpp - GitHub; CPAN的主要维护者。)