Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу).
Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу). Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу). Homepage Карта сайта Версия для печати

Джентльменский набор Web-разработчика   Ларри Уолл о Perl6   Наблы Система Orphus
 

15. Имена переменных и комментарии,  или ломка стереотипов

[15 февраля 2002 г.]

Эта статья фактически представляет собой продолжение темы одиннадцатой наблы. Я попробую высказать некоторые предложения насчет того, как желательно оформлять код собственной программы. Преимущественно речь пойдет о Perl, и вот почему.

Язык Perl имеет дурную славу. Особенно когда речь заходит о том, какой же некрасивый код программист вынужден на нем писать. Конечно, в этом есть большая доля истины (пожалуй, даже больше половины), однако многое зависит также и от того, насколько аккуратен человек, пишущий на Perl. В мире существуют тысячи больших и маленьких программ, которые были написаны в спешке или просто неаккуратно. Именно из-за них Perl называют языком, на котором можно писать, но не читать его. Но попробуем сломать стереотипы, хотя бы некоторые.

Стереотип первый: используйте длинные имена переменных и функций.

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

Вот несколько примеров. Конечно, они не бесспорны, и многие люди не согласятся с выводами, которые я тут делаю. Что же, критика всегда приветствуется. Помните также, что каждый программист придерживается своего собственного стиля оформления исходников, но в то же время все будут просто счастливы, если бы весь мир вдруг однажды утром проснулся и начал писать в едином стиле.

Первый пример — печально известный по четвертой набле модуль CGI.pm. Для того, чтобы заставить его выводить ошибки в браузер, а не в файлы журнала Apache, необходимо написать:

use CGI::Carp qw(fatalsToBrowser);

Мы видим, что строка чересчур уж длинна. Даже для того действия, которое она выполняет (я имею в виду, что, хотя ошибки и отображаются в браузере, предупреждения — пожалуй, наиболее эффективный механизм отладки, — просто игнорируются). Вообще, сама фраза fatalsToBrowser уж очень напыщенная. Хотя приведенный выше код приходится писать лишь один раз на протяжении скрипта (хотя, конечно же, можно воспользоваться и более удобным модулем CGI::WebOut), она все равно является хорошим примером чрезмерного «усердия» разработчиков.

Второй пример — из исходных кодов сервера Apache. Разработчики постоянно (иногда оправданно, но чаще всего — нет) употребляют слишком длинные имена функций — например, os_init_job_environment. Дополнительное удлинение дают также символы подчерка, которые особенно любят применять программисты на «старом добром» Си. Я бы назвал эту фунцию значительно короче — например, вот так: osIniJobEnv. Во-первых, слово ini (во многом благодаря Microsoft и расширениям файлов) уже не спутаешь ни с чем другим, кроме как с Init.

Лирическое отступление 
Тут, правда, экономия всего в одну букву, что не очень критично.

Во-вторых, в английском языке не так уж и много слов, начинающися с env. К тому же, сокращение «env» встречается очень часто и во многих языках программирования, и ни у кого не может вызвать затруднение в его толковании как «Environment» (если бы это было «Envelope», то сокращением стало бы envel). Наконец, в-третьих (и тут я согласен с позицией Sun), подчерки слишком удлиняют идентификаторы, и несколько короче будет применять следующие правила при именовании объектов в программах:

  1. все переменные — с маленькой буквы;
  2. все константы — только большими буквами;
  3. имена классов и типов — с большой буквы;
  4. вместо подчерков начинать новое слово с большой буквы.

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

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

Третий (а также четвертый, пятый и т. д.) пример — это весь API Windows. Уж не знаю, что сподвигло авторов вводить функции вида GetWindowModuleFileName, когда точно то же самое можно сказать несколько короче: getWinModFName. Так как слово Window, опять же, является очень распространенным, никто и не заподозрит в Win ничего иного. Более того, вполне можно было бы сократить его и до одной-единственной буквы W без потери читабельности.

Итак, все, к чему я клоню — так это к тому, что функции надо называть не длинно, а понятно. Если некоторое сокращение совершенно однозначно, не задумывайтесь ни на секунду. Так, смело заменяйте «to» на «2» (пример: exe2bin), «For» на «4» (пример: doChk4Objs, расшифруйте это имя сами).

Лирическое отступление 
Как ни странно, но остроумные сокращения запоминаются даже лучше, чем исходные слова. Этим в последнее время постоянно злоупотребляют — например, назвать утилиту для сервера Apache именем Comanche, хотя и остроумно, но уж слишком наиграно. Тем не менее, услышав такое название хоть раз и улыбнувшись, запоминаешь его на всю жизнь.

А сейчас я выскажу еще одну, гораздо более еретическую мысль. Уведите детей от монитора. Готовы?.. Итак. Известно, что в объектно-ориентированной программе примерно половина всех имен функций начинаются со слов get и set. Вы никогда не задумывались, зачем мы постоянно тянем за собой груз из дополнительных 2 символов, когда «get» можно было бы сократить до g, а «set» — до s?.. В реальности такой стиль практически никто не использует, однако, попробовав применять сокращения, вы быстро поймете, что они ничуть не менее информативны.

Лирическое отступление 
Еще лучше в этом вопросе поступили разработчики Delphi и C# (в которых можно объявлять свойства класса и работать с ними, как с обычными полями структуры). К сожалению, корпорация Sun никогда не задумывалась, что будущее за свойствами (и в этом вопросе C# явно обскакал Java), а потому наизобретала всяких спецификаций о том, как надо писать get- и set-методы (например, JavaBeans).

Теперь о переменных. Мы уже договорились, что нужно начинать их с маленькой буквы (в Perl — после доллара, собаки или процента). Это относится в равной степени и к массивам, и к хэшам, и даже к ссылкам на объекты. Исключение из этого правила, которое предлагает Ларри Уолл (изобретатель Perl) — это называть файловые переменные только большими буквами, как и константы. Трудно понять, откуда берется такое предложение, однако, так как переменные этого типа используются гораздо реже всех остальных, мы можем тут пойти на поводу у разработчиков.

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

# int factorial(int $n)
# Возвращает факториал аргумента.
sub factorial
{  my ($number)=@_;
   my $factorial=1;
   for(my $index=1; $index<=$number; $index++) {
      $factorial*=$index;
   }
   return $factorial;
}

Чайник 

Да-да, я знаю — тут шрифт помельче. Да возрадуются любители разрешения экрана 800x600, что у них тоже нет полосы прокрутки снизу!

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

# int factorial(int $n)
# Возвращает факториал аргумента.
sub factorial
{  my ($n)=@_;
   my $r=1;
   for(my $i=1; $i<=$n; $i++) {
      $r*=$i;
   }
   return $r;
}

Чайник 

Данный пример является лишь моделью, поэтому он и не так нагляден, как хотелось бы. Реальное преимущество от коротких имен переменных можно почувствовать только в больших программах. Что же это за преимущество?.. Очень просто: короткие имена (конечно, в разумных пределах) не загромождают код и позволяют лучше видеть его логику.

Естественно, сокращать до «абсурдных» размеров следует не все имена, а только попадающие под следующие категории.

  • Счетчик циклов одинарной вложенности традиционно рекомендуется именовать $i, и никак иначе. При этом и определение, и приращение этого счетчика по возможности лучше производить не в теле цикла, а в заголовке for (как это сделано в примере выше). Если счетчик должен инициализироваться до входа в цикл, значит, с вашей программой что-то не так.

  • Если цикл имеет двойную вложенность, некоторые люди называют второй счетчик $j. Мне лично это не нравится, потому что довольно легко спутать $i и $j в теле цикла (они оба с точкой и расположены на клавиатуре почти рядом). Поэтому рекомендую называть внешний счетчик $n, а внутренний — $i. То же самое относится и к другим переменным, которые любят использовать математики: $k, $l и т. д. — лучше вообще не использовать их в качестве счетчиков (см. про эти переменные ниже).

  • Если в процессе вычисления необходимо накапливать некоторый результат (как в примере с факториалом), его можно обозначить просто буквой $r (от слова «Result»). Если вы сильны в ассемблере и обладаете некоторым чувством юмора, можете назвать такую переменную $eax.

  • Переменная $k используется для хранения некоторого коэффициента, получаемого либо временно в процессе вычислений, либо же до начала цикла.

  • Переменная $l может использоваться для промежуточного хранения длины некоторой строки (чтобы не вызывать десять раз strlen()). Она очень похожа по виду на $1 («доллар-один»), но используется только в арифметическом контексте, а значит, скорее всего, при просмотре листинга вы их не перепутаете.

  • Наконец, переменную $p удобно использовать в качестве указателя (от «Pointer» или «Position») при перемещении по строке во время ее сканирования. Конечно, в Perl часто можно обходиться одними лишь регулярными выражениями (и в этом его сила), но изредка приходится прибегать и к «дедовским» способам.

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

    Стереотип второй: программа должна быть самодокументированной.

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

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

    Если вы не писатель в душе, то ненавидите вставлять комментарии во время кодирования. В крайнем случае, откладываете это «на потом»: «Я вставлю комментарии после того, как программа заработает». Обычно это «потом» так и не настает, так что программа остается без комментариев, а значит, низкого качества (что бы там ни говорили, в большинстве случаев это так).

    Про то, как желательно составлять комментарии, мы поговорим чуть ниже, а пока замечу одну деталь. Вы можете комментировать вашу программу, как вам вздумается. Но гораздо удобнее и приятнее будет придерживаться одного определенного стиля комментирования, как вы делаете это при написании кода. Четко выраженный стиль комментирования позволит также в перспективе создать программу, которая будет «шерстить» ваш код, выделяя из него комментарии и идентификаторы. Хороший пример этому — вставлять описания функций непосредственно перед ее заголовком. В дальнейшем с помощью автоматических утилит будет возможно выделить такие описания и даже создать на их основе нечто вроде документации.

    Разработчики Perl, видимо, думали над этим вопросом, потому что встроили в язык инструкции специального вида — так называемые POD-директивы (от «Plain Old Document» — «Старый добрый документ»). С помощью этих директив в теории можно писать документацию прямо среди инструкций кода, оформляя ее специальным образом. При этом для транслятора она будет выглядеть не более, чем комментариями. Вот пример:

    =head2 Математические функции.
    
    =over 5 
    
    =item int factorial(int $n)
    
    Возвращает факториал своего аргумента.
    
    =cut
    
    sub factorial
    {  my ($n)=@_;
       my $r=1;
       for(my $i=1; $i<=$n; $i++) {
          $r*=$i;
        }
       return $r;
    }

    К сожалению, тут имеет место совершенно явная недоработка: для того, чтобы инструкции POD воспринимались инструментами формирования документации, необходимо, чтобы каждая директива была окружена с обеих сторон пустыми строками! Это весьма прискорбно, учитывая, что ни один программист в здравом уме не будет так «разбавлять» свою программу (как это показано в примере). Мне совершенно непонятно, почему разработчики спецификации POD, находясь, вообще говоря, в авангарде технологии (насколько мне известно, в тот момент не существовало другого языка, кроме Perl, позволяющего проделывать такие вещи), допустили столь чудовищную ошибку. Кто-то что-то говорил о лучшей производительности программ выделения документации — им-де не надо особо думать, стоит ли =cut в начале строки или в ее середине. На фоне современных и чрезвычайно быстрых алгоритмов работы с регулярными выражениями это оправдание выглядит более, чем смешно.

    Тем не менее, POD все еще применяется (и весьма успешно) для создания технической документации, но обычно одним большим блоком и после конца скрипта (чаще всего за инструкцией __END__). Он довольно удобен (если не считать, что в директиве создания списка =over приходится зачем-то явно указывать число элементов, хотя программа вполне могла бы подсчитать их сама). Рекомендую составлять окончательную документацию к Perl-модулям именно в этом формате — конечно же, никто этим не отменяет необходимость писать комментарии и в середине кода.

    Стереотип третий: чем больше комментариев в программе, тем лучше.

    Это утверждение прямо противоположно предыдущему, но никто и не говорил, что мы будем рассматривать только стереотипы из «одной корзины». Если вас иногда «заносит» и вы начинаете писать огромное количество комментариев в своем коде (а именно это частенько происходит со мной), если в вашей программе комментарии составляют более половины текста, время остановиться и задуматься. Налицо некоторая ошибка, но в чем же она заключается?..

    И тут мы сталкиваемся с проблемой, у которой, вообще говоря, нет определенного решения. Можно лишь дать некоторые рекомендации и примеры того, когда следует писать комментарии, а когда — воздержаться, потому что и так очевидно, что делает программа. В этом смысле значительное преимущество имеют лица с раздвоением личности (я уже как-то писал, что эта особенность вредна для всего, чего угодно, но только не для программирования). Итак, написали пару строчек кода, — попробуйте взглянуть на них «свежим взглядом», как будто бы текст создали не вы, а кто-то еще. Если вам кажется, что код непонятен, то... Как вы думаете, что нужно сделать?..

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

    Предположим, вы все-таки решили вставить комментарий (естественно, это когда-нибудь произойдет). Что именно в нем написать?.. Не пытайтесь описать кусок кода изолированно: лучше опишите общими словами, что он делает, а также какие результаты будут получены после его выполнения. Вот пример неверного комментария:

    # $elt хранит первый элемент списка.
    my $elt=$obj->getFirst();
    # Инициализируем нулем.
    my $n=0;
    # Пока текущий элемент существует...
    while($elt) {
        # Увеличить $n...
        $n++;
        # $elt = следующий элемент
        $elt=$elt->getNext();
    }

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

    Приведу теперь пример того, как можно откомментировать этот код. Наверняка мой вариант тоже не идеален, но он, по крайней мере, более информативен.

    # $obj - список окон на рабочем столе.
    # Считаем, сколько их.
    my $elt=$obj->getFirst();
    my $n=0;
    while($elt) {
        $n++;
        $elt=$elt->getNext();
    }
    # Теперь $n - число окон.

    Наверное, вы поняли, что я сделал: просто убрал комментарии из мест, где и так все понятно. Перебирать связанный список можно только одним способом — нет никакой необходимости это разъяснять. Зато нужно пояснить, что же в реальности хранится в той или иной переменной — ведь программист может случайно наткнуться на этот код, не глядя на всю его «предысторию».

    Так как в этом примере читабельность кода между комментариями, в общем-то, не имеет особого значения, можно записать его короче и изящнее — вот так:

    # $obj - список окон на рабочем столе.
    # Считаем, сколько их.
    my $n=0;
    for(my $e=$obj->first(); $e; $e=$e->next(), $n++) {}
    # Теперь $n - число окон.

    Чайник 

    К моему большому сожалению, длинная строчка этого кода не влезала бы на страницу в браузере, если бы я не сократил имена методов до first() и next(). А значит, пример произвел бы скорее негативное, чем положительное впечатление. Мне даже пришлось уменьшить шрифт, чтобы не появились линейки прокрутки внизу.

    Итак, комментарии к коду должны быть такими, чтобы, если бы кто-нибудь вдруг стер весь код, оставив только эти самые комментарии, по ним нельзя было бы восстановить программу в первозданном виде. Это утверждение аналогично предыдущему: комментарии не должны лишь повторять то, что делает программа — скорее они должны описывать возможные тонкие места.

    Задержим взгляд на последней мысли. Что такое вообще «тонкое место»? Как его можно распознать?.. Вообще говоря, никак — тут нужно положиться на интуицию или что-то, ее заменяющее. Предыдущий пример в свете сказанного мог бы выглядеть так (я перейду назад к «длинному» варианту, чтобы больше не мучаться с размером шрифта):

    # $obj - список окон на рабочем столе.
    # Считаем, сколько их.
    my $elt=$obj->getFirst();
    my $n=0;
    # ВНИМАНИЕ! Следующее далее условие не работает, 
    # если список является кольцевым, а не 
    # оканчивается элементом undef.
    while($elt) {
        $n++;
        $elt=$elt->getNext();
    }
    # Теперь $n - число окон.

    Внося дополнительный комментарий в этот «распухающий» демонстрационный код, мы тем самым оказываем помощь себе же, когда в будущем захотим переделать структуру списка в $obj.

    Чайник 

    Конечно, из кода и так ясно, что список не может быть закольцован — иначе цикл просто будет работать до бесконечности. Поэтому, конечно же, если вы когда-нибудь будете писать именно такой код, не используйте комментарий. Приведенный пример реально «работает» только в больших и сложных циклах.

    Грамотный и добросовестный программист всегда ведет журнал изменений своего проекта, что тоже можно отнести к комментированию. Я его обычно не веду — лень. Тем не менее, могу посоветовать не вести такой журнал в начале каждого файла с исходниками, потому что не вести его в отдельном текстовом документе значительно сложнее. Старайтесь во время не ведения журнала записывать дату изменения (по прошествии пары лет будет очень интересно на нее взглянуть), его серьезность (хотя бы то, является ли это исправлением ошибки — BUGFIX — или же просто добавлением возможностей). Можно также указать, кто именно инициировал изменение (например, заказчик, или даже вы сами). В принципе, все это начнет постепенно очень сильно смахивать на CVS, и в этом плюс ведения журнала изменений: чем скорее вы приобщитесь в CVS и поймете необходимость его использования, тем лучше. Я пока так и не приобщился, но понимание необходимости уже на подходе.

    Если в некотором месте кода вы нашли ошибку и хотите ее исправить, постарайтесь оставить на ее месте не «дыру» (то есть, пустое место), а комментарий, описывающий, в чем же была проблема. Особенно это относится к вашим же решениям улучшить тот или иной алгоритм в конкретной ситуации. Игнорирование этой рекомендации может привести к весьма курьезным случаям, когда вы 3 раза подряд наступаете на одни и те же грабли, «улучшая» код, а потом вдруг вспоминая, что именно это улучшение вы уже неоднократно делали и выяснялось: оно не может работать.

    Стереотип четвертый: не вылезайте за правую границу поля редактирования.

    Собственный опыт подсказывает: если вы изо всей силы избегаете писать код, символы которого «залезают» за правый край поля в редакторе (т.е. пересекают 80-й столбец), это может помочь лишь в одном случае — когда вам вдруг вздумается распечатать на принтере свой многотомный листинг. Зададимся вопросом: а многие ли современные программисты печатают свои листинги на принтере?.. Вспомните, когда вы сами делали это в последний раз, и для чего (чтобы на досуге почитать? чтобы сохранить «твердую копию» на всякий случай? чтобы убедиться, что алгоритм работает верно?).

    Лирическое отступление 
    Может быть, тут как-нибудь можно еще задействовать и бабушкину печатную машинку, а то что она без дела на шкафу пылится...

    Сначала кажется, что, если код не помещается на страницу по горизонтали, его будет трудно читать. Можете проверить сами: это не соответствует действительности. Если даже вы и заинтересуетесь одной из немногих строк, которые «не влезли», то наверно уж не побрезгаете пару раз нажать стрелку вправо или немного поелозить линейкой прокрутки (для любителей меткой стрельбы). Конечно, я не призываю писать код квадратиком, а значит, 95% строк программы будут все-таки не длиннее 50-60 символов. И уж как писать эти строки — дело ваше.

    Длинные строки довольно удобны в следующих случаях.

    • Некоторый небольшой фрагмент программы логически атомарен и не может изменяться без нарушения логики работы. Например, при использовании в Perl функции sort тело анонимной функции-сортировщика вполне может быть довольно длинным (приведенный пример сортирует содержимое директории в алфавитном порядке, чтобы каталоги шли перед файлами):
      @r=sort { -d $a && !-d $b && -1 or -d $b && !-d $a && 1 or $a cmp $b } readdir(DIR);

      Лирическое отступление 
      Я вынужден уже в третий раз оправдываться: окно браузера несовершенно, а потому использовать его для выражения программистских идей — все равно, что делать дизайн для сайта в PaintBrush-е. Вы должны понимать, что тот символ разрыва строки, который вы сейчас видите, в реальном коде не существует — там все вытянуто в одну строчку.

    • Фрагмент представляет собой строку текста небольшой длины, но из-за применения отступов (табуляторов, показывающих уровень вложенности блоков кода) в коде ее правый край «не влез». Не буду на этот раз приводить пример — жалко ваши глаза, смотрящие в глубину браузера.
    • Обстоятельства вынуждают вас написать некоторый очень нудный код, который, тем не менее, необходимо включать во все скрипты. Вы не хотите, чтобы в него кто-то вносил изменения, а также чтобы он мозолил вам глаза, занимая несколько строк. Например:
      use lib ($ENV{HOME}||"$ENV{DOCUMENT_ROOT}/.."). '/библиотеки';
      См. пятую наблу, если интересуетесь, зачем кому-то может понадобиться такой код.

    Чайник 

    Если я вас так и не убедил, последний аргумент. Почему вы считаете, что вам мешает «вылезание» текста за правый край, в то время как на выход за нижний край страницы вы не обращаете ровно никакого внимания, называя это «скроллингом»?.. Если вы скажете, что «у вас мышь с колесиком», то я отвечу: часто в этом случае колесика 2, для вертикальной и горизонтальной прокрутки. Кроме того, стрелки на клавиатуре пока что никто не отменял.

    Стереотип пятый: чем меньше функций, тем короче и быстрее код.

    Наверное, каждый программист слышал о том, что вызов функции в программе требует некоторых накладных расходов, связанных с передачей параметров, сохранением точки возврата и т. д. Многие утилиты (такие как flex в Unix), казалось бы, подтверждают эту мысль: они предпочитают генерировать длинные функции, состоящие из сотен и более строк, чтобы только не распыляться на вызов более мелких подпрограмм. Наконец, даже авторы крупных программ (Apache, sendmail и т. д.) частенько создают громадные функции с множеством параметров.

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

    Первая и, пожалуй, самая неожиданная мысль: длина функций в программе не должна превышать 20 строк. Если функция длинее, попытайтесь разбить ее на как можно более независимые блоки (подфункции), полезные и сами по себе. Девять шансов из десяти, что они потом пригодятся вам и в других местах программы.

    Лирическое отступление 
    Конечно, цифру 20 не нужно понимать как «божественное число». Это лишь примерная оценка, верная для подавляющего большинства функций программы. Тут может быть и 30, и 40 строк, но важно понимать, что строчек должно быть немного — гораздо меньше, чем все мы привыкли писать.

    Таким образом, если вы пишете функцию и обнаруживаете, что она длинее 20 строк (кстати, то же относится и к главной исполняемой части программы), значит, что-то тут не так. Возможно, стоит подумать: нельзя ли кое-что исправить в концепции, чтобы появилась возможность не писать длинный код. Чаще всего ответ на этот вопрос положителен.

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

    Второе замечание (о цене вызова функции) для таких языков, как Perl, вообще часто оказывается абсурдным. По крайней мере, пока программа не начнет явно «тормозить», и пока вы не запустили профайлер и не определили, где же ее «узкое место», глупо пытаться что-то оптимизировать. Это напоминает экономию на спичках.

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

    И последнее: большое число параметров функции — точно такое же зло, как и длинные подпрограммы. Если параметров становится слишком много, стоит решить, нельзя ли передавать их все через один хэш. Самое главное преимущество такого шага очевидно: не надо помнить, в каком порядке передаются функции аргументы. Посмотрим, как поступили авторы IO::Socket:

    $s = IO::Socket::INET->new(
      PeerAddr => 'www.perl.org',
      PeerPort => 'http(80)',
      Proto    => 'tcp', #!
    );

    Чайник 

    Обратите внимание на строку, помеченную как #!. Казалось бы, там лишняя запятая. На практике же код прекрасно работает. При этом, добавляя новую строку, вы можете уже не гнать курсор назад с тем, чтобы поставить недостающую запятую — она уже есть. Трюк с запятой позволяет делать и язык Си, но не Java. Почему разработчики последней опять отказались от очередной прекрасно зарекомендовавшей себя возможности, остается загадкой.

    Но не впадайте в искушение использовать «хэш аргументов» абсолютно во всех функциях. У авторов модуля были реальные причины вводить подобный синтаксис: во-первых, в будущем вполне могли добавляться новые параметры конструктора, а во-вторых, даже существующих параметров сейчас весьма много, и большинство из них — необязательные. Так что я привел данный код только для того, чтобы показать, что имеется в виду, когда говорится об одном большом «хэше аргументов».

    Итак, прием с «хэшем аргументов» стоит применять в случае, если параметров у функции много и большинство из них необязательны (то есть, могут иметь значения по умолчанию). Во всех остальных ситуациях избегайте этого трюка, потому что он слишком громоздок для частого применения.

    Лирическое отступление 
    На этом позвольте объявить об окончании сегодняшней наблы. Я выкладываю ее на сайт еще «сырой», подразумевая в ближайшие дни некоторую «чистку и шлифовку». Продолжение следует.

  •  
    Рекламный блок
       

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

    Важное объявление:
        автор категорически против копирования и распространения в Интернете всех статей «Куроводства» с возрастом, меньшим 6 месяцев. Печальный опыт «расползания» чрезвычайно устаревших ошибочных версий статьи про Apache действительно объясняет такое решение.

    Орфография на «Куроводстве»:
        если вы заметили орфографическую, стилистическую или другую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Выделенный текст будет немедленно отослан вебмастеру, а Вы даже ничего и не заметите — настолько быстро все произойдет.

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

    Параметры этой страницы
       
    GZip

    Ссылки от спонсоров
        www.shop-energo.ru


    Дмитрий Котеров | 15 февраля 2002 г. ©1999-2016 | Генеральный спонсор: Хостинг «Джино» | Контакт Вернуться к оглавлению