perl用双引号封装单个变量

Rad*_*ris 7 syntax perl double-quotes

在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");
Run Code Online (Sandbox Code Playgroud)

据我所知,没有理由这样做.当我使用旧脚本时,我通常会删除引号,因此我的编辑器将它们变为变量而不是字符串.

我认为他们在某个地方看到了这个并复制了风格而没有理解为什么会这样.我错过了什么吗?

谢谢.

dao*_*oad 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";
Run Code Online (Sandbox Code Playgroud)

在这里,stringification创建了一个副本并将其传递给子例程,绕过Perl的引用语义传递.通常认为调用变量是不礼貌的,所以你可能没问题.

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

还有一个可能会发生的深刻的怪异事情.如果您正在使用XS代码来查看在函数的标量参数上设置的标志,那么对标量进行字符串化是一种直接的方式来说明perl,"让我成为一个很好的干净的新字符串值",只有字符串标记和没有数字标志.

我确信99.9%规则还有其他奇怪的例外.这些是一些.在删除引号之前,请花点时间检查这样的怪异废话.如果你确实发生了合法使用,请添加一个注释,将引号标识为可行的kludge,并给出它们存在的理由.


Eug*_*ash 6

在这种情况下,双引号是不必要的.而且,使用它们是低效的,因为这会导致原始字符串被复制.

但是,有时您可能希望使用此样式来"字符串化"对象.例如,URIojects支持字符串化:

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

  • @ikegami:但我们正在查看"//"之前的历史代码.并且vi击败emacs,Linux击败FreeBSD,11个天使可以在pin的头上跳舞:) (2认同)

ike*_*ami 6

我不知道为什么,但它是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
Run Code Online (Sandbox Code Playgroud)

通过创建字符串的副本,它可以对对象进行字符串化.在处理根据其参数是否为引用而改变其行为的代码时,这可能很有用.

在以下示例中,显式字符串化已完成,因为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
Run Code Online (Sandbox Code Playgroud)