在Perl中,有没有理由将单个变量封装在双引号中(没有连接)?
我经常在我正在处理的程序的源代码中找到这个(10年前由不在这里工作的人写的):
my $sql_host = "something";
my $sql_user = "somethingelse";
# a few lines down
my $db = sub_for_sql_conection("$sql_host", "$sql_user", "$sql_pass", "$sql_db");
据我所知,没有理由这样做。当我使用旧脚本时,我通常会删除引号,因此我的编辑器将它们变为变量而不是字符串。
我认为他们在某个地方看到了这个并且复制了这个风格而没有理解为什么会如此。我错过了什么吗?
谢谢。
答案 0 :(得分:7)
这一切都是显式字符串化变量。在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";
这里,stringification创建了一个副本并将其传递给子例程,绕过Perl的引用语义传递。通常认为调用变量是不礼貌的,所以你可能没事。
您还可以在此处对对象或其他值进行字符串化。例如,undef
字符串化为空字符串。对象可以指定在进行字符串化时运行的任意代码。可以使用具有不同数值和字符串值的双值标量。这是一种指定您想要字符串形式的方法。
还有一件可能会发生的令人毛骨悚然的事情。如果您正在使用XS代码来查看在函数的标量参数上设置的标志,那么对标量进行字符串化是一种直接的方式来说明perl,“让我成为一个很好的干净的新字符串值”,只有字符串标记和没有数字标记。
我确信99.9%规则还有其他奇怪的例外。这些是一些。在删除引号之前,请花点时间检查这样的怪异废话。如果你确实发生了合法使用,请添加一个注释,将引号标识为可行的kludge,并给出它们存在的理由。
答案 1 :(得分:6)
在这种情况下,双引号是不必要的。而且,使用它们是低效的,因为这会导致原始字符串被复制。
但是,有时您可能希望使用此样式来“字符串化”对象。例如,URI
对象支持字符串化:
my $uri = URI->new("http://www.perl.com");
my $str = "$uri";
答案 2 :(得分:6)
我不知道为什么,但它是Perl新手常用的模式。这通常是一种浪费(就像你发布的片段一样),但我可以想到两种用途。
它具有创建与原始字符串具有相同值的新字符串的效果,并且在非常罕见的情况下非常有用。
在下面的示例中,执行显式复制以保护$ x不被子修改,因为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
答案 3 :(得分:2)
在你的情况下,报价完全没用。我们甚至可以说这是错误的,因为这不像其他人写的那样惯用。
然而,有时可能需要引用变量:这明确地触发变量值的字符串化。如果值为双变量,或者如果它们是具有overload ed字符串化的祝福值,则字符串化可能会为某些值提供不同的结果。
以下是双变量的示例:
use 5.010;
use strict;
use Scalar::Util 'dualvar';
my $x = dualvar 1, "2";
say 0+$x;
say 0+"$x";
输出:
1
2
答案 4 :(得分:0)
我的理论一直是人们从其他语言过来的坏习惯。并不是说他们在想“我会一直使用双引号”,但他们只是没想到!
我会诚实地说,我曾经陷入这个陷阱,因为我从Java来到Perl,所以肌肉记忆在那里,并且一直在射击。
PerlCritic终于让我摆脱了这个习惯!
它肯定会让你的代码更有效率,但是如果你没有考虑是否想要对你的字符串进行插值,你很可能会犯下愚蠢的错误,所以我会更进一步说它很危险。 / p>