如何在字符串中运行代码(相当于Ruby的#{})

时间:2017-08-23 04:57:37

标签: perl string-interpolation

我知道我们可以在Ruby中将任何代码放到#{}#{}中的代码将被计算,然后插入到字符串中。

Perl中有没有相同的东西?

2 个答案:

答案 0 :(得分:10)

来自Using references in perlref

  

在您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何地方,您可以使用包含正确类型的引用的简单标量变量替换标识符
  ...
  在您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何地方,您可以使用BLOCK替换标识符,返回正确类型的引用。

所以

perl -Mstrict -wE'my $x = 2.6; say "Integer part: ${ \( int $x ) }"'

您可以在其中运行代码,在\(...)内部返回标量,以获取其引用,然后@{...}取消引用它。同样,您可以生成一个arrayref并在其周围使用@{...}

perl -Mstrict -wE'$_ = q(silly,it,is); say "Got: @{ [ /(\w+)/g ] }"'

和哈希类似。但是,这也是一个表达式返回一个标量

perl -wE'say "$_ squared: @{[ $_**2 ]}" for 1..10'

哪个更好,更多"通常"用过的。感谢ysth发表评论。

请注意,[ ]强加了列表context,其中返回通常与标量上下文中的不同(并且\(LIST)在其他帐户中出错)。一个很好的例子是localtime。标量返回可以由[scalar localtime]强制执行。感谢ikegami发表评论。

请注意,您不会被拖入使用symbolic references。另请参阅that in perlfaq7

这假设您正在考虑{...}中的代码是字符串的一部分。如果你有一个字符串以及它作为代码执行的内容,那就是eval EXPR的作用。

但请注意,始终有更好的方法来满足您的需求。

一些例子

my $str = sprintf "Squared: %6.3f", $x**2;
my $str = "He said: " . join ' ', split /,/, 'yes,it,is';  #/
say "Variable is: ", ( $x // 'undef');

或使用do { ... };来评估受限制范围内的任何代码并返回结果,然后可以将结果与其他字符串连接或连接。

讨论的主题为in perlfaq4,并在本帖子顶部链接的perlref部分的末尾进行了讨论。

\(LIST)中,引用列表中的每个元素perl -wE'say for \(1,2)'。然后标量上下文中的逗号运算符执行其操作,一个接一个地丢弃左侧操作数,${ \(LIST) }最终为列表的最后一个元素提供服务。

答案 1 :(得分:2)

如果您允许使用CPAN,Quote::Code也可以使用。

从概要:

use Quote::Code;
print qc"2 + 2 = {2 + 2}";  # "2 + 2 is 4"
my $msg = qc{The {$obj->name()} is {$obj->state()}.};