Цитировать ключи при использовании хеша в Perl - хорошая идея?
Я работаю над чрезвычайно большой устаревшей базой кода Perl и пытаюсь перенять множество лучших практик, предложенных Дэмианом Конвеем в Лучшие практики Perl. Я знаю, что всегда - это щекотливая тема для программистов, но, надеюсь, я смогу получить хорошие ответы на этот вопрос, не разжигая пламенную войну. Я также знаю, что это, вероятно, то, с чем многие люди не будут спорить из-за того, что это незначительная проблема, но я пытаюсь получить надежный список рекомендаций, которым нужно следовать, работая над этой базой кода.
В Книга Perl Best Practices от Дэмиана Конвея есть этот пример, который показывает, как выравнивание помогает разборчивости раздела кода, но в нем не упоминается (нигде в книге, которую я могу найти) что-либо о цитировании хеш-ключей.
$ident{ name } = standardize_name($name);
$ident{ age } = time - $birth_date;
$ident{ status } = 'active';
Разве это не лучше было бы написать в кавычках, чтобы подчеркнуть, что вы не используете голые слова?
$ident{ 'name' } = standardize_name($name);
$ident{ 'age' } = time - $birth_date;
$ident{ 'status' } = 'active';





Лучше без кавычек. Он в {}, поэтому очевидно, что вы не используете голые слова, плюс его легче читать и печатать (на два символа меньше). Но все это, конечно, зависит от программиста.
Хеш-ключи без кавычек получили внимание на уровне синтаксиса со стороны Ларри Уолла, чтобы убедиться, что для них не будет никакой другой причины, кроме наилучшей практики. Не переживайте по поводу цитат.
(Между прочим, кавычки на ключи массива находятся - лучшая практика в PHP, и их неиспользование может иметь серьезные последствия, не говоря уже о тоннах E_WARNING. Хорошо в Perl! = Хорошо в PHP.)
Есть ли где-нибудь интервью или статья с этой ссылкой на Ларри Уолла? Я бы с удовольствием это прочитал.
Не знаю. Пока это происходило, я был в соответствующем списке рассылки.
Лучше использовать кавычки, потому что они позволяют использовать специальные символы, не разрешенные в голых словах. Используя кавычки, я могу использовать специальные символы моего родного языка в хэш-ключах.
Идите с цитатами! Они визуально разбивают синтаксис, и больше редакторов будут поддерживать их в выделении синтаксиса (эй, даже Stack Overflow выделяет версию цитаты). Я также утверждаю, что вы быстрее заметите опечатки, если редакторы будут проверять, что вы закончили цитату.
Итак, вы предлагаете цитаты, потому что ваш редактор покажет вам, когда вы забыли закончить цитату?
Как ни странно, я думаю, что это то, что он говорит. Либо так, либо он говорит, что, поскольку строки обычно выделяются более заметно, чем ванильный код, легче увидеть опечатки в ваших хеш-ключах?
Оруэлловский? Действительно? Не ленитесь. Достаточно сложно поддерживать большое количество Perl без ленивых или «умных» разработчиков. Любая практика, которую вы можете сделать, чтобы код было легче читать и поддерживать другим, - это шаг в правильном направлении.
Или, возможно, мы можем опустить кавычки, чтобы выявить плохие синтаксические выделения. :)
По крайней мере, цитирование предотвращает выделение синтаксиса зарезервированных слов в не очень идеальных редакторах. Проверить:
$i{keys} = $a;
$i{values} = [1,2];
...
Я не думаю, что в этом есть лучшая практика. Лично я использую их в хэш-ключах так:
$ident{'name'} = standardize_name($name);
но не используйте их слева от оператора стрелки:
$ident = {name => standardize_name($name)};
Не спрашивайте почему, я просто так делаю :)
Я думаю, самое важное, что вы можете сделать, - это всегда, всегда, всегда:
use strict;
use warnings;
Таким образом, компилятор поймает за вас любые семантические ошибки, уменьшая вероятность того, что вы что-то опечатаете, каким бы способом вы ни выбрали.
И второе по важности - быть последовательным.
Да, последовательность - ключ к успеху. Я пытаюсь добиться единообразия стиля во всей этой кодовой базе, и это одна из областей, которая варьируется от сценария к сценарию. К счастью, все сценарии действительно используют strict, но в большинстве из них в настоящее время не используются предупреждения. Это исправляется по мере того, как я иду. :)
При указании хэш-ключей константной строки всегда следует использовать (одинарные) кавычки. Например, $hash{'key'}. Это лучший выбор, потому что он избавляет от необходимости думать об этой проблеме и приводит к согласованному форматированию. Если вы иногда опускаете кавычки, вы должны не забывать добавлять их, если ваш ключ содержит внутренние дефисы, пробелы или другие специальные символы. Вы должен используете кавычки в этих случаях, что приводит к несогласованному форматированию (иногда без кавычек, иногда в кавычках). Цитированные ключи также с большей вероятностью будут выделены синтаксисом вашего редактора.
Вот пример, когда использование соглашения «цитируется иногда, а не цитируется в другое время» может вызвать у вас проблемы:
$settings{unlink-devices} = 1; # I saved two characters!
Это прекрасно скомпилируется под use strict, но не совсем то, что вы ожидаете во время выполнения. Хеш-ключи - это строки. Строки должны быть заключены в кавычки в соответствии с их содержанием: одинарные кавычки для буквальных строк, двойные кавычки, чтобы разрешить интерполяцию переменных. Цитируйте свои хеш-ключи. Это самое безопасное соглашение, которое проще всего понять и соблюдать.
Очевидно, это был субъективный вопрос, поэтому я выбрал субъективный ответ. После прочтения всех ответов я склоняюсь к использованию кавычек всегда, а не только в тех случаях, когда они необходимы как для согласованности, так и для возможного уменьшения количества ошибок.
Что на самом деле делает $settings{unlink-devices} = 1;?
@Despertar Вы можете увидеть это, запустив `perl -MO = Deparse -e" $ settings {unlink-devices} = 1 "`, что даст $settings{unlink -'devices'} = 1;. разорвать связь - это функция. Вы получите $settings{0}=1.
Я предпочитаю обходиться без кавычек, если мне не нужна интерполяция строк. И тогда я использую двойные кавычки. Я сравниваю это с буквальными числами. Perl действительно позволит вам делать следующее:
$achoo['1'] = 'kleenex';
$achoo['14'] = 'hankies';
Но этого никто не делает. И это не помогает с ясностью просто потому, что мы добавляем еще два символа для ввода. Точно так же, как иногда нам нужен слот №3 в массиве, иногда нам нужна запись PATH из %ENV. Одиночные кавычки, насколько мне известно, добавляют ясности нет.
Способ, которым Perl анализирует код, делает невозможным использование других типов «голых слов» в хеш-индексе.
Пытаться
$myhash{shift}
и вы собираетесь получить только элемент, хранящийся в хэше под ключом 'shift', вы должны сделать это
$myhash{shift()}
чтобы указать, что вы хотите, чтобы первый аргумент индексировал ваш хеш.
Кроме того, я использую jEdit, визуальный редактор ТОЛЬКО (который я видел - помимо emacs), который позволяет ты полностью контролировать выделение. Так что для меня это вдвойне ясно. Все, что похоже на предыдущее, получает KEYWORD3 ($ myhash) + SYMBOL ({) + LITERAL2 (shift) + SYMBOL (}), если перед закрывающими фигурными скобками стоит парантез, он получает KEYWORD3 + SYMBOL + KEYWORD1 + SYMBOL (()}). Кроме того, я, вероятно, тоже отформатирую его так:
$myhash{ shift() }
Что-то вроде $ myhash {shift} именно поэтому вы хотите использовать кавычки, ИМХО. Конечно, ты знает, что вы делаете, но как насчет бедняги shmoe, которая должна поддерживать ваш код после вашего ухода? Он или она посмотрит на это и поймет: «Топорник» действительно имел в виду клавишу Shift или Shift ()?
Вот почему «shift», вероятно, никогда не будет явным ключом, просто случайным - называется $ hash {$ this_should_be_here}.
Вы также можете поставить перед ключом «-» (минус), но имейте в виду, что это добавляет «-» к начало вашего ключа. Из моего кода:
$args{-title} ||= "Intrig";
Я также использую одинарные кавычки, двойные кавычки и способы без кавычек. Все в одной программе :-)
Ребята, вы меня убиваете :-) Какого черта? Это был субъективный вопрос?
Проблема в том, что -title! = To title. Это два разных ключа.
Есть ли значок для самых популярных и самых отрицательных ответов? Думаю, это победитель :-)
Я всегда использовал их без кавычек, но я бы повторил использование строгих правил и предупреждений, поскольку они выбирают большинство распространенных ошибок.
За исключением того, что strict ничего не делает для хеш-ключей, и предупреждение, скорее всего, сработает далеко от ошибочного чтения хеш-кода. Это один из стимулов для вывернутых наизнанку объектов и злополучного псевдохэша (теперь ограниченные хеши).
Однако он может предупреждать об использовании неопределенных значений.
Да, когда используется хэш значение, обычно далеко от места ошибки и поэтому не очень полезен. Это не означает, что не следует использовать строгие правила и предупреждения, просто они не решают эту проблему.
Я сам задавался вопросом об этом, особенно когда обнаружил, что допустил несколько ошибок:
use constant CONSTANT => 'something';
...
my %hash = ()
$hash{CONSTANT} = 'whoops!'; # Not what I intended
$hash{word-with-hyphens} = 'whoops!'; # wrong again
Сейчас я стараюсь применять кавычки универсально для каждого хеша, если они нужны хотя бы одному из буквальных ключей; и используйте круглые скобки с константами:
$hash{CONSTANT()} = 'ugly, but what can you do?';
Я не использую кавычек, просто потому, что меньше нужно печатать, читать и беспокоиться. Случаи, когда у меня есть ключ, который не будет цитироваться автоматически, очень редки, чтобы не стоить всей дополнительной работы и беспорядка. Возможно, мой выбор хеш-ключей изменился, чтобы соответствовать моему стилю, что тоже хорошо. Полностью избегайте крайних случаев.
По той же причине я использую " по умолчанию. Для меня чаще помещать переменную в середину строки, чем использовать символ, который я не хочу интерполировать. То есть я чаще писал 'Hello, my name is $name', чем "You owe me $1000".
Я никогда не использую хеш-ключи в одинарных кавычках. Я знаю, что {} в основном работает так же, как кавычки, за исключением особых случаев (+ и двойные кавычки). Мой редактор тоже знает это и дает мне несколько цветовых подсказок, чтобы убедиться, что я сделал то, что задумал.
Использование одинарных кавычек повсюду кажется мне «защитной» практикой, которую применяют люди, не знающие Perl. Избавьтесь от износа клавиатуры и изучите Perl :)
С этой напыщенной речью, настоящая причина, по которой я публикую этот комментарий ... в других комментариях, похоже, упускается из виду тот факт, что + "отключает цитирование" голого слова. Это означает, что вы можете написать:
sub foo {
$hash{+shift} = 42;
}
или же:
use constant foo => 'OH HAI';
$hash{+foo} = 'I AM A LOLCAT';
Итак, довольно ясно, что +shift означает «вызвать функцию сдвига», а shift означает «строку« сдвиг »».
Я также отмечу, что cperl-mode правильно выделяет все различные случаи. Если этого не произойдет, пингуйте меня в IRC, и я исправлю это :)
(О, и еще кое-что. Я цитирую имена атрибутов в Moose, как и в has 'foo' => .... Это привычка, которую я приобрел во время работы со Стеваном, и хотя я думаю, что это выглядит хорошо ... она немного несовместима с остальными моего кода. Возможно, я скоро перестану этим заниматься.)
Что такое «cperl-mode»? Что-то в Emacs?
Отсутствие кавычек дает дополнительное преимущество: вы никогда не попадете себе в ногу случайно, используя двойные кавычки и интерполируя строки.
print "Hello $planet{"Earth"}\n"; вызовет синтаксические ошибки, аprint "Hello $planet{Earth}\n";- нет.