Что делает поддерживаемый код Perl? - PullRequest
23 голосов
/ 03 декабря 2010

Я пишу на Perl уже несколько лет, и это мой предпочтительный язык для обработки текста (многие проблемы генетики / геномики, над которыми я работаю, легко сводятся к проблемам обработки текста). Perl как язык может быть очень щадящим, и на Perl можно писать очень плохой, но функциональный код. Буквально на днях мой друг сказал, что он называет Perl только для записи языком: напиши один раз, пойми один раз и никогда не пытайся вернуться и починить его после его завершения.

Хотя я определенно был виновен в написании плохих сценариев, мне кажется, что я также написал некоторый очень понятный и поддерживаемый код на Perl. Однако, если бы меня спросили, что делает код понятным и понятным, я не смог бы дать уверенный ответ.

Что делает поддерживаемым код Perl? Или, может быть, лучший вопрос - что делает код на Perl трудным для поддержки? Давайте предположим, что я не единственный, кто будет поддерживать код, и что другие участники, такие как я, не профессиональные программисты на Perl, а ученые с опытом программирования.

Ответы [ 8 ]

30 голосов
/ 03 декабря 2010

Что делает код Perl не поддерживаемым? Практически все, что делает любую другую программу неуправляемой. Предполагая что-либо кроме короткого сценария, предназначенного для выполнения четко определенной задачи, это:

  • Глобальные переменные
  • Отсутствие разделения интересов: монолитные сценарии
  • НЕ использовать самодокументируемые идентификаторы (имена переменных и имена методов). Например. Вы должны знать, какова цель переменной по ее имени. $c плохо. $count лучше. $token_count хорошо.
    • Вычеркнуты идентификаторы заклинаний. Размер программы больше не имеет первостепенного значения.
    • Подпрограмма или метод с именем doWork ничего не говорит
    • Упростите поиск источника символов из другого пакета. Либо используйте явный префикс пакета, либо явно импортируйте каждый символ, используемый через use MyModule qw(list of imports).
  • Perl-конкретны:
    • Чрезмерная зависимость от ярлыков и непонятных встроенных переменных
    • Злоупотребление прототипами подпрограмм
    • не использует strict и не использует warnings
  • Изобретая велосипед, а не используя установленные библиотеки
  • Не используется согласованный стиль отступа
  • Не использовать горизонтальные и вертикальные пробелы для направления читателя

и т. Д. И т. Д.

По сути, если вы думаете, что Perl -f>@+?*<.-&'_:$#/%!, и вы стремитесь писать что-то подобное в производственном коде, тогда да, у вас будут проблемы.

Люди часто путают вещи, которые программисты Perl делают для удовольствия (например, JAPH, гольф и т. Д.), С тем, как должны выглядеть хорошие программы Perl.

Мне до сих пор неясно, как они могут отделить свои умы код , написанный для IOCCC от поддерживаемого C.

15 голосов
/ 03 декабря 2010

Я предлагаю:

  1. Не становитесь слишком умными с Perl.Если вы начнете играть в гольф с кодом, это приведет к тому, что код станет труднее для чтения.Код, который вы пишете, должен быть читаемым и понятным больше, чем должен быть умным.
  2. Документируйте код.Если это модуль, добавьте POD, описывающий типичное использование и методы.Если это программа, добавьте POD для описания параметров командной строки и типичного использования.Если есть сложный алгоритм, документируйте его и, если возможно, предоставьте ссылки (URL).
  3. Используйте форму регулярных выражений /.../x и документируйте их.Не все хорошо понимают регулярные выражения.
  4. Знайте, что такое связь, и плюсы / минусы высокой / низкой связи.
  5. Знайте, что такое сплоченность, и плюсы / минусы высокой / низкой когезии.
  6. Используйте модули соответствующим образом.Хорошая, четко определенная, содержательная концепция - отличный модуль.Повторное использование таких модулей является целью.Не используйте модули просто для уменьшения размера монолитной программы.
  7. Напишите модульные тесты для своего кода.Хороший набор тестов позволит вам не только доказать, что ваш код работает сегодня, но и завтра.Это также позволит вам сделать более смелые изменения в будущем, с уверенностью, что вы не сломаете старые приложения.Если вы что-то ломаете, значит, ваш набор тестов был недостаточно широким.

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

13 голосов
/ 04 декабря 2010

Я не использую все Perl Best Practices , но именно для этого Дамиан написал это.Независимо от того, пользуюсь ли я всеми предложениями, все они, по крайней мере, заслуживают рассмотрения.

9 голосов
/ 03 декабря 2010

Что делает поддерживаемым код Perl?

Как минимум:

use strict;
use warnings;

См. perldoc perlstyle для некоторых общих рекомендацийВаши программы легче читать, понимать и поддерживать.

5 голосов
/ 04 декабря 2010

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

Perl позволяет вамнаписать ОЧЕНЬ краткий код, но точные куски не означают, что они должны быть объединены вместе.

Пустое пространство имеет много смысла / использования, когда мы говорим о читабельности, не все из них широко используются, но наиболее полезны:

  • Пробелы вокруг токенов для облегчения их разделениявизуально.

    Это пространство вдвойне важно в Perl из-за преобладания символов линейного шума даже в коде Perl лучшего стиля.

    Я нахожу $myHashRef->{$keys1[$i]}{$keys3{$k}} менее читабельным в 2 часа ночи в середине производственной аварии по сравнению с разнесенными: $myHashRef->{ $keys1[$i] }->{ $keys3{$k} }.

    В качестве примечания: если вы обнаружите, что ваш код выполняет много глубоких вложенных ссылочных выражений, начинающихся с одного и того же корня, вам следует обязательно рассмотреть назначение этого корня во временный указатель (см. Комментарий / ответ Синан).

    Частичным, но ОЧЕНЬ важным частным случаем этого являются, конечно, регулярные выражения.Различие было проиллюстрировано до смерти во всех основных материалах, которые я помню (PBP, книга RegEx O'Reilly и т. Д.), Поэтому я не буду удлинять этот пост, если кто-то не попросит примеры в комментариях.

  • Правильный и равномерный отступ.D'о.Очевидно.Тем не менее, я вижу слишком много кода, не читаемого на 100% из-за дерьмового отступа, и еще менее читаемого, когда половина кода была добавлена ​​с помощью табуляции человеком, редактор которого использовал 4-символьные вкладки, а другой - человеком, редактор которого использовал 8-символьные вкладки.Просто настройте свой кровавый редактор на создание мягких (например, космических) вкладок и не делайте других несчастными.

  • Пустые строки вокруг логически отдельных единиц кода (как блоков, так и просто наборовлинии).Вы можете написать программу на 10000 строк Java на 1000 строк хорошего Perl.Теперь не чувствуйте себя Бенедиктом Арнольдом, если вы добавляете 100-200 пустых строк к этим 1000, чтобы сделать вещи более читабельными.

  • Разделение сверхдлинных выражений на несколько строк, за которыми следуют...

  • Правильное вертикальное выравнивание.Обратите внимание на разницу между

    if ($some_variable > 11 && ($some_other_bigexpression < $another_variable || $my_flag eq "Y") && $this_is_too_bloody_wide == 1 && $ace > my_func() && $another_answer == 42 && $pi == 3) {
    

    и

    if ($some_variable > 11 && ($some_other_bigexpression < $another_variable || 
        $my_flag eq "Y") && $this_is_too_bloody_wide == 1 && $ace > my_func()
        && $another_answer == 42 && $pi == 3) {
    

    и

    if (   $some_variable > 11
        && ($some_other_bigexpression < $another_variable || $my_flag eq "Y")
        && $this_is_too_bloody_wide == 1
        && $ace > my_func()
        && $another_answer == 42
        && $pi == 3) {
    

    Лично я предпочитаю исправить вертикальное выравнивание еще одним шагом, выровняв LHS иRHS (это особенно удобно в случае длинных SQL-запросов, но также и в самом коде Perl, как в таких длинных условных выражениях, как и в множестве строк присваиваний и инициализации хеш / массивов):

    if (   $some_variable               >  11
        && ($some_other_bigexpression   <  $another_variable || $my_flag eq "Y")
        && $this_is_too_bloody_wide    ==  1
        && $ace                         >  my_func()
        && $another_answer             ==  42
        && $pi                         ==  3  ) {
    

    Asпримечание: в некоторых случаях код можно сделать еще более читабельным / обслуживаемым, если не иметь таких длинных выражений.Например, если содержимое блока if(){} представляет собой return, то выполнение нескольких операторов if/unless, каждый из которых имеет блок возврата, может быть лучше.

4 голосов
/ 04 декабря 2010

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

большинство людей будут ссылаться на регулярные выражения при обсуждении читабельности.регулярные выражения - это dsl, встроенный в perl, и вы можете читать их или нет.если кто-то не может найти время, чтобы понять что-то такое базовое и существенное для многих языков, я не беспокоюсь о том, чтобы попытаться преодолеть какой-то предполагаемый разрыв в когнитивных способностях ... он должен просто разобраться, прочитать perldocs и задать вопросы, где это необходимо.

другие будут ссылаться на использование Perl коротких форм, таких как @_, $!и т. д. все они легко двусмысленны ... меня не интересует, чтобы Perl выглядел как Java.

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

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

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

2 голосов
/ 03 декабря 2010

Я бы сказал, модели упаковки / объекта, которые отражаются в структуре каталогов для файлов .pm. Для своего доктора философии я написал довольно много кода на Perl, который потом снова использую. Это было для автоматического генератора диаграмм LaTeX.

1 голос
/ 06 июля 2012

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

Это правда, что вы обычно не должны быть слишком умными с действительно плотными операторами типа а-ля return !$@;#% и тому подобными, но с большим количеством умных, используя операторы обработки списков, такие как map и grep и list- возвращение контекста от подобных split и подобных операторов, чтобы написать код в функциональном стиле, может внести положительный вклад в ремонтопригодность. У моего последнего работодателя у нас также были некоторые шикарные функции манипулирования хешем, которые работали аналогичным образом (hashmap и hashgrep, хотя технически мы только кормили их списками четного размера). Например:

# Look for all the servers, and return them in a pipe-separated string
# (because we want this for some lame reason or another)
return join '|', 
       sort
       hashmap {$a =~ /^server_/ ? $b : +()} 
       %configuration_hash;

См. Также Perl более высокого порядка , http://hop.perl.plover.com - хорошее использование метапрограммирования может сделать определение задач более согласованным и читабельным, если вы не сможете помешать самому метапрограммированию.

...