perl encapsulate single variable in double quotes

五迷三道 提交于 2019-12-01 01:53:01

问题


In Perl, is there any reason to encapsulate a single variable in double quotes (no concatenation) ?

I often find this in the source of the program I am working on (writen 10 years ago by people that don't work here anymore):

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");

As far as I know there is no reason to do this. When I work in an old script I usualy remove the quotes so my editor colors them as variables not as strings.

I think they saw this somewhere and copied the style without understanding why it is so. Am I missing something ?

Thank you.


回答1:


All this does is explicitly stringify the variables. In 99.9% of cases, it is a newbie error of some sort.

There are things that may happen as a side effect of this calling style:

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";

Here, stringification created a copy and passed that to the subroutine, circumventing Perl's pass by reference semantics. It's generally considered to be bad manners to munge calling variables, so you are probably okay.

You can also stringify an object or other value here. For example, undef stringifies to the empty string. Objects may specify arbitrary code to run when stringified. It is possible to have dual valued scalars that have distinct numerical and string values. This is a way to specify that you want the string form.

There is also one deep spooky thing that could be going on. If you are working with XS code that looks at the flags that are set on scalar arguments to a function, stringifying the scalar is a straight forward way to say to perl, "Make me a nice clean new string value" with only stringy flags and no numeric flags.

I am sure there are other odd exceptions to the 99.9% rule. These are a few. Before removing the quotes, take a second to check for weird crap like this. If you do happen upon a legit usage, please add a comment that identifies the quotes as a workable kludge, and give their reason for existence.




回答2:


In this case the double quotes are unnecessary. Moreover, using them is inefficient as this causes the original strings to be copied.

However, sometimes you may want to use this style to "stringify" an object. For example, URI ojects support stringification:

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



回答3:


I don't know why, but it's a pattern commonly used by newcomers to Perl. It's usually a waste (as it is in the snippet you posted), but I can think of two uses.


It has the effect of creating a new string with the same value as the original, and that could be useful in very rare circumstances.

In the following example, an explicit copy is done to protect $x from modification by the sub because the sub modifies its argument.

$ 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

By virtue of creating a copy of the string, it stringifies objects. This could be useful when dealing with code that alters its behaviour based on whether its argument is a reference or not.

In the following example, explicit stringification is done because require handles references in @INC differently than strings.

$ 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



回答4:


In your case quotes are completely useless. We can even says that it is wrong because this is not idiomatic, as others wrote.

However quoting a variable may sometime be necessary: this explicitely triggers stringification of the value of the variable. Stringification may give a different result for some values if thoses values are dual vars or if they are blessed values with overloaded stringification.

Here is an example with dual vars:

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

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

Output:

1
2



回答5:


My theory has always been that it's people coming over from other languages with bad habits. It's not that they're thinking "I will use double quotes all the time", but that they're just not thinking!

I'll be honest and say that I used to fall into this trap because I came to Perl from Java, so the muscle memory was there, and just kept firing.

PerlCritic finally got me out of the habit!

It definitely makes your code more efficient, but if you're not thinking about whether or not you want your strings interpolated, you are very likely to make silly mistakes, so I'd go further and say that it's dangerous.



来源:https://stackoverflow.com/questions/9157700/perl-encapsulate-single-variable-in-double-quotes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!