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

问题描述 投票:9回答:5

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

use constant FOO => 'bar';

my $msg = <<EOF;
Foo is currently <whatever goes here to expand FOO>
EOF
perl
5个回答
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;

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;

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;

Output:

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

Using a method:

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

Aside:

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用作任何其他标量值,并且不能修改它。您尝试修改该值,您将获得:

尝试修改只读值...


3
投票

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

use Readonly;
Readonly my $FOO => 'bar';

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

附:模块Const::Fast(灵感来自noduleReadonly)似乎是一个更好的选择。


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。)

© www.soinside.com 2019 - 2024. All rights reserved.