我确信有几种方法可以在下面的<>中获取值'bar'进行插值,但最简洁的方法是什么,为什么?
use constant FOO => 'bar';
my $msg = <<EOF;
Foo is currently <whatever goes here to expand FOO>
EOF
使用Const::Fast而不是Readonly
或constant
。它们插入而没有任何扭曲。见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;
这里有两种文档:
<<'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;
许多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
用作任何其他标量值,并且不能修改它。您尝试修改该值,您将获得:
尝试修改只读值...
您是否考虑过使用"read-only variables"作为常量? perlcritic在严重等级4处推荐它(默认为5级)
use Readonly;
Readonly my $FOO => 'bar';
my $msg = <<"EOF";
Foo is currently <$FOO>
EOF
附:模块Const::Fast
(灵感来自noduleReadonly
)似乎是一个更好的选择。
晚会,但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
源预处理器here(see also this answer)中使用了这种技术。 (免责声明:我现在是perlpp
的主要维护者 - GitHub; CPAN。)