10

我确信有几种方法可以在下面的 <> 中插入值“bar”,但是最干净的方法是什么,为什么?

use constant FOO => 'bar';

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

5 回答 5

15

这里有两种文档:

  • <<'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;
于 2013-04-03T16:59:38.133 回答
9

许多 CPAN 模块在常量方面比use constantpragma 做得更好,但问题在于它们不是标准 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;

输出:

这是我的很长
我的变量的值
也恰好包含
常数的值
'FOO' 具有价值
这是我对 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其用作任何其他标量值,并且不能修改。您尝试修改该值并获得:

尝试修改只读值...

于 2013-04-03T21:38:49.793 回答
4

使用Const::Fast代替Readonlyor constant。它们在没有任何扭曲的情况下进行插值。请参阅CPAN 模块以定义常量

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

...

如果您想要数组或散列常量,或不可变的丰富数据结构,请使用 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;
于 2013-04-03T19:29:51.173 回答
3

您是否考虑过使用“只读变量”作为常量?
perlcritic 将其推荐为严重级别 4(默认为级别 5)

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

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

PS Module Const::Fast(受 nodule 启发Readonly)似乎是一个更好的选择。

于 2013-04-03T17:13:11.127 回答
1

迟到了,但是另一个版本的 arrayref 技巧可以在标量上下文中做到这一点:${\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的源预处理器中使用了该技术(另请参阅此答案)。(免责声明:我现在是- GitHub ; CPAN的主要维护者。)perlpp

于 2016-12-09T16:43:23.447 回答