Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl用双引号封装单个变量_Perl_Syntax_Double Quotes - Fatal编程技术网

perl用双引号封装单个变量

perl用双引号封装单个变量,perl,syntax,double-quotes,Perl,Syntax,Double Quotes,在Perl中,是否有任何理由将单个变量封装在双引号中(无串联) 我经常在我正在工作的程序的源代码中发现这一点(10年前由不再在这里工作的人编写): 据我所知,没有理由这样做。当我在旧脚本中工作时,我通常会删除引号,以便编辑器将它们作为变量而不是字符串进行着色 我想他们在某个地方看到了这一点,并在不理解其原因的情况下复制了这种风格。我错过什么了吗 谢谢。在这种情况下,不需要双引号。此外,使用它们效率低下,因为这会导致复制原始字符串 但是,有时您可能希望使用此样式“字符串化”对象。例如,项目支持字符

在Perl中,是否有任何理由将单个变量封装在双引号中(无串联)

我经常在我正在工作的程序的源代码中发现这一点(10年前由不再在这里工作的人编写):

据我所知,没有理由这样做。当我在旧脚本中工作时,我通常会删除引号,以便编辑器将它们作为变量而不是字符串进行着色

我想他们在某个地方看到了这一点,并在不理解其原因的情况下复制了这种风格。我错过什么了吗


谢谢。

在这种情况下,不需要双引号。此外,使用它们效率低下,因为这会导致复制原始字符串

但是,有时您可能希望使用此样式“字符串化”对象。例如,项目支持字符串化:

my $uri = URI->new("http://www.perl.com");
my $str = "$uri";

我不知道为什么,但这是Perl新手常用的模式。这通常是一种浪费(正如您发布的代码片段中所述),但我可以想到两种用途


它的作用是创建一个与原始字符串具有相同值的新字符串,这在非常罕见的情况下非常有用

在下面的示例中,显式复制是为了保护$x不被sub修改,因为sub修改了它的参数

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f($x);
   say $x;
'
Abc
Abc

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f("$x");
   say $x;
'
Abc
abc

通过创建字符串的副本,它将对象字符串化。当处理基于其参数是否为引用而改变其行为的代码时,这可能很有用

在下面的示例中,执行显式字符串化是因为
require
处理
@INC
中的引用与字符串不同

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib $lib;
   use DBI;
   say "ok";
'
Can't locate object method "INC" via package "Path::Class::Dir" at -e line 4.
BEGIN failed--compilation aborted at -e line 4.

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib "$lib";
   use DBI;
   say "ok";
'
ok

我的理论一直是,来自其他语言的人习惯不好。这并不是说他们在想“我会一直使用双引号”,而是他们根本没有在想

老实说,我曾经掉进过这个陷阱,因为我是从Java来到Perl的,所以肌肉内存就在那里,而且一直在启动

PerlCritic终于让我改掉了这个习惯


这无疑会提高代码的效率,但如果你不考虑是否需要插入字符串,你很可能会犯愚蠢的错误,因此我会进一步说这是危险的。

所有这一切都是显式地字符串化变量。在99.9%的案例中,这是某种新手错误

这种通话方式可能会产生一些副作用:

my $foo = "1234";
sub bar { $_[0] =~ s/2/two/ }
print "Foo is $foo\n";
bar( "$foo" );
print "Foo is $foo\n";
bar( $foo );
print "Foo is $foo\n";
在这里,字符串化创建了一个副本并将其传递给子例程,从而绕过了Perl的“按引用传递”语义。通常认为,大嚼调用变量是不礼貌的,所以您可能没事

您还可以在此处对对象或其他值进行字符串化。例如,
undef
字符串化为空字符串。对象可以指定字符串化时要运行的任意代码。可以使用具有不同数值和字符串值的双值标量。这是一种指定需要字符串形式的方法

还有一件可怕的事情可能正在发生。如果您使用的XS代码查看在函数的标量参数上设置的标志,那么字符串化标量是一种直截了当的方式,可以对perl说,“让我成为一个干净的新字符串值”,只使用字符串标志,不使用数字标志


我相信99.9%的规定还有其他奇怪的例外。这些是一些。在删除引号之前,花一点时间检查是否有像这样奇怪的废话。如果你的引用是合法的,请添加一条注释,说明这些引用是可行的,并给出它们存在的理由

在你的情况下,引用是完全无用的。我们甚至可以说这是错误的,因为这不像其他人所写的那样是惯用语

然而,有时引用变量可能是必要的:这明确地触发了变量值的字符串化。如果这些值是双变量,或者它们是经过字符串化处理的幸运值,则字符串化可能会为某些值提供不同的结果

以下是双变量的示例:

use 5.010;
use strict;
use Scalar::Util 'dualvar';

my $x = dualvar 1, "2";
say 0+$x;
say 0+"$x";
输出:

1
2

如果未启用警告,它还会悄悄地将
undef
变为空字符串,不是吗?但我不认为这是一个有效的用法,我可能不会考虑任何没有警告的东西。“MU太短:是的,<代码> unDEF< <代码>将变成<代码>”(<代码> >(不管警告是否启用),但是它不会悄悄地加上警告,您将得到“未初始化的连接值”。投诉。@ikegami:但我们正在查看以前的历史代码。vi打败了emacs,Linux打败了FreeBSD,11个天使可以在pin头上跳舞:)我可以想象一个需要显式字符串化对象的接口的不幸碰撞。在这种情况下,我倾向于显式调用类的底层stringfication方法:
my$str=$foo->as_string()在某些情况下,字符串生成器可能是匿名的(不要这样做!),或者您依赖于对象之间的多态性,这些对象在其接口中不共享公共字符串化方法(叹气)。在这种情况下,您别无选择,只能执行
my$str=“$foo”#有意stringify$foo-foo::Bar需要curds,但不需要whey
注意注释。Re“如果您使用的XS代码查看函数标量参数上设置的标志”,我之前展示了一个纯Perl示例。任何使用
ref()
的方法都可以。这是一个很好的问题,因为这里的答案显示了在重新分解旧代码时应该多么小心-可能有一个很好的理由让某些东西一开始看起来像是坏样式。第一种情况可以描述为“使用显式副本的变通方法”。我建议在代码中添加注释
1
2