Существуют ли какие-либо недостатки для интерполяции в Perl?
Я только начинаю с Perl (буквально сегодня), и я читаю бесплатную онлайн-версию Начиная с Perl. Раньше в книге упоминалось, что двойные кавычки будут интерполированы. Тем не менее, в каждом примере с использованием функции печати (до сих пор... я около страницы 66) автор передает скалярные переменные в качестве параметра списка. Возможно, я прыгаю с пистолетом, и это будет объяснено позже, но есть ли какая-то причина выбора метода A по методу B?
Метод A:
$myVar = "value";
print "Current value is ", $myVar, "\n";
Метод B:
$myVar = "value";
print "Current value is $myVar\n";
На мой взгляд, метод B более удобен. Есть ли предпочтительный способ в сообществе? Или, может быть, некоторые скрытые хотча, которые делают один метод более безопасным для использования над другим и т.д.?
ТИА
Ответы
Ответ 1
В простом примере, таком как это, нет.. но рассмотрим, было ли $myVar
на самом деле чем-то более сложным, например глубокое разыменование хеш-ссылки или вызов метода. Некоторые вещи интерполируются внутри строк (большинство ссылок на объекты), но вызовы методов не делают. Кроме того, массивы выполняют разные вещи при распечатке напрямую или через интерполяцию в строку.
PS. Добро пожаловать в Perl; пожалуйста, наслаждайтесь путешествием!:)
Ответ 2
Там определенно скрыты gotchas - perl будет иметь дело с простыми именами переменных, а выражения типа
"$array[$subscript]"
и
"$hashref->{key}"
без проблем. Однако, поскольку ваши выражения становятся все более сложными, в конечном итоге perl не сможет определить, где ваше выражение останавливается, а остальная часть вашей строки начинается.
В этой статье представлено множество подробностей Переменная интерполяция в двуконусных строках (изначально здесь, но сейчас)
Ответ 3
Там '
gotcha:
$owner = "John";
$item = "motorcycle".
print "This is $owner $item.\n"; # Oops, parsed as $owner::s
но вышеприведенное может быть безопасно записано как
print "This is ${owner} $item.\n";
Ответ 4
Есть несколько вещей, которые нужно учитывать при интерполяции, хотя, как только вы узнаете о них, вы вряд ли когда-либо делаете их по ошибке.
Помещение имени переменной рядом с допустимым текстом идентификатора. Perl находит самое длинное допустимое имя переменной и не имеет значения, было ли оно определено ранее. Вы можете указать часть имени переменной с фигурными выражениями:
my $p = 'p';
print "Mind your $ps and qs\n"; # $ps, not $p
print "Mind your ${p}s and qs"; # now its $p
Теперь, в этом примере, я забыл апостроф. Если я его добавлю, у меня есть другая проблема, поскольку апостроф раньше был разделителем пакетов из старых дней, и он все еще работает. Скобки тоже работают:
my $p = 'p';
print "Mind your $p and q's\n"; # $p::s, not $p
print "Mind your ${p} and q's"; # now its $p
Perl также может интерполировать обращения отдельных элементов к хэшам и массивам, поэтому размещение указателей рядом с именем переменной может сделать то, что вы не хотите:
print "The values are $string[$foo]\n"; That the element at index $foo
print "The values are $string{$foo}\n"; That the value for the key $foo
Если вам нужен адрес электронной почты в строке, вы можете забыть, что Perl интерполирует массивы. Perl использовал для того, чтобы сделать фатальную ошибку, если вы не избежали @
:
print "Send me mail at [email protected]\n"; # interpolates @example
print "Send me mail at joe\@example.com\n";
Поскольку Perl использует обратную косую черту для выхода из некоторых символов, вам нужно удвоить их, если вы хотите получить буквальный текст:
print "C:\real\tools\for\new\work"; # not what you might expect
print "C:\\real\\tools\\for\\new\\work"; # kinda ugly, but that life
print "C:/real/tools/for/new/work"; # Windows still understands this
Несмотря на эти незначительные ошибки, я очень скучаю по легкости, с которой я могу построить строки в Perl, если мне нужно использовать другой язык.
Ответ 5
Метод A должен быть:
$myVar = "value";
print 'Current value is ', $myVar, "\n";
Когда вы произвольно указываете строку, Perl не утруждает себя чтением всего, что ищет вещи для интерполяции, поэтому, если у вас длинная строка, которая не нуждается в интерполяции, возможно, быстрее использовать одинарные кавычки и добавить динамические части, как указано выше.
Однако это микро-оптимизация, которая на самом деле не имеет большого значения.
Другим случаем использования метода А является строка, в которой содержатся escape-символы, которые вы не хотите беспокоить:
$myVar = 12000;
print 'Conversion from $US to $CND: ', $myVar,\n";
В этом случае вы не хотите, чтобы Perl искал переменные $US
и $CND
, вы просто хотите, чтобы строка имела знак доллара в нем.
В конце концов, это в основном вопрос стиля. Обычно я стараюсь избегать строк с двойными кавычками, если они мне не нужны.
Ответ 6
так как мы говорим об интерполяции gotchas, стоит упомянуть, что если вы используете одиночные кавычки, чтобы избежать интерполяции, вам все равно нужно избежать конечной косой черты:
'c:\files\' #parse error
'c:\files\\' #correct
это потому, что последний символ первой строки выглядит как экранированная одиночная кавычка, а не ограничитель строки. также экранированная косая черта будет преобразована в одну косую черту в одинарных кавычках
Ответ 7
Если вы достигли Perl, то вы ищете быстрый способ добиться успеха. Кроме того, вам предлагается сделать это так, как это наиболее похоже на ваш образ мыслей (отсюда и девиз Perl: TMTOWTDI, там больше, чем один способ сделать это). Поэтому: в зависимости от того, что вам легче писать, каким бы способом вы, скорее всего, не поняли, когда вернетесь к коду позже, так вам следует делать это (все остальное, например, дать предполагаемый результат, быть равным).
Если вы обеспокоены "безопасностью", как вы предлагаете, узнайте о tainting, который помогает защитить вас от потенциально вредных данных из внешнего мира.
Ответ 8
(Вероятно, это должна быть вики сообщества.)
Единственная очевидная проблема, которая приходит мне на ум, - это интерполяция массивов. Сравнить
print @arr, "\n";
с
print "@arr\n";
Кроме того, иногда сложное разыменование не очень хорошо работает с интерполяцией, но это редкость.
Ответ 9
Как аутсайдер Perl, который не знаком с любыми редакторами, зависящими от perl, и их полномочиями по подсчету, я голосую за использование одинарных кавычек, когда это возможно. Это упрощает читателю, что эта строка не содержит ничего, что будет интерполировано каким-либо образом.
Ответ 10
Интерполяция - это большое упрощение и экономия времени. Но можно зайти слишком далеко.
Вы можете сделать некоторые причудливые вещи с интерполяцией, если хотите.
@foo = 0..10;
print "$foo[2*3]"; # prints 6
И для захватывающей произвольной интерполяции вы можете использовать эту мерзость:
print "@{[ some_function_call('in list context') ]}";
Если вы действительно хотите сделать интерполированные вызовы функций, для этого есть модуль. Проверьте Interpolation. Это позволяет вам делать такие вещи:
use Interpolation;
print "I like $eval{ what_I_like() };
sub what_like_like {
return 'pie';
}
И многое, многое другое.
Для фона на этом модуле см. Identity.pm: Очень смешной модуль и Interpolation.