Perl инкапсулирует одну переменную в двойных кавычках - PullRequest
7 голосов
/ 06 февраля 2012

Есть ли в 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");

Насколько я знаю, нет причин делать это. Когда я работаю со старым сценарием, я обычно удаляю кавычки, поэтому мой редактор окрашивает их как переменные, а не строки.

Я думаю, что они где-то видели это и копировали стиль, не понимая, почему это так. Я что-то упустил?

Спасибо.

Ответы [ 5 ]

7 голосов
/ 06 февраля 2012

Все, что это делает - это явная строковая переменная.В 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%.Это несколько.Прежде чем удалять кавычки, потратьте секунду, чтобы проверить на странную чушь, подобную этой.Если вы столкнулись с законным использованием, пожалуйста, добавьте комментарий, который идентифицирует цитаты как работоспособный кладж, и укажите причину их существования.

6 голосов
/ 06 февраля 2012

Я не знаю почему, но эта модель часто используется новичками в Perl.Обычно это пустая трата времени (как в опубликованном вами фрагменте), но я могу вспомнить о двух случаях.


В результате создается новая строка с тем же значением, что и у оригинала, иэто может быть полезно в очень редких случаях.

В следующем примере выполняется явная копия для защиты $ x от модификации подпрограммой, поскольку подпрограмма изменяет свой аргумент.

$ 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
6 голосов
/ 06 февраля 2012

В этом случае двойные кавычки не нужны.Более того, их использование неэффективно, поскольку это приводит к копированию исходных строк.

Однако иногда вы можете захотеть использовать этот стиль для «строкового преобразования» объекта.Например, URI ojects поддерживает строковое преобразование:

my $uri = URI->new("http://www.perl.com");
my $str = "$uri";
2 голосов
/ 06 февраля 2012

В вашем случае цитаты совершенно бесполезны. Мы можем даже сказать, что это неправильно, потому что это не идиоматично, как писали другие.

Однако иногда может потребоваться заключить в кавычки переменную: это явно вызывает строковое определение значения переменной. Стрификация может дать другой результат для некоторых значений, если эти значения являются двойными переменными или если они являются благословенными значениями с перегрузкой ред.

Вот пример с двумя переменными:

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

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

Выход:

1
2
0 голосов
/ 06 февраля 2012

Моя теория всегда состояла в том, что люди приходят с других языков с вредными привычками.Дело не в том, что они думают: «Я буду использовать двойные кавычки все время», а в том, что они просто не думают!

Я буду честен и скажу, что я попадал в эту ловушку, потому что яЯ пришел в Perl из Java, так что у меня была свободная память, и он продолжал стрелять.

PerlCritic наконец-то вывел меня из привычки!

Это определенно сделает ваш код более эффективным, но если выВы не думаете о том, хотите ли вы, чтобы ваши строки были интерполированы, вы, скорее всего, сделаете глупые ошибки, поэтому я бы пошел дальше и сказал, что это опасно.

...