Главная страница


ru.cgi.perl

 
 - RU.CGI.PERL ------------------------------------------------------------------
 From : Artem Chuprina                       2:5020/400     11 Jul 2002  14:51:25
 To : "Dmitry Koteroff"
 Subject : Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>
 -------------------------------------------------------------------------------- 
 
 Здравствуй, Dmitry Koteroff.
 
 DK> > $ perl -w -c WebIn.pm
 DK> > Name "CGI::WebIn::IN" used only once: possible typo at WebIn.pm line 48.
 DK> > Name "CGI::WebIn::MULTICHUNK_SIZE" used only once: possible typo at
 DK> > WebIn.pm line 36.
 DK> > Name "CGI::WebIn::CANUPL_FILE" used only once: possible typo at WebIn.pm
 DK> > line 35. Name "CGI::WebIn::Div1" used only once: possible typo at WebIn.pm
 DK> > line 42. Name "CGI::WebIn::Div2" used only once: possible typo at WebIn.pm
 DK> > line 43. Name "CGI::WebIn::Bad" used only once: possible typo at WebIn.pm
 DK> > line 105. WebIn.pm syntax OK
 
 DK> А теперь попробуйте вот так:
 
 DK> $ cat test.pl
 DK> #!/usr/bin/perl -w
 DK> use CGI::WebIn;
 
 DK> $ perl -w test.pl
 
 DK> Hи одной ошибки и предупреждения. Hо ведь этот модуль только так и
 DK> используется (из командной строки его запускать нельзя, потому что это
 DK> МОДУЛЬ, а не скрипт).
 
 Что, и компилировать его из командной строки тоже нельзя? Или благородный дон
 ключа -c не заметил?
 
 DK> > Хорошо, оставим эти варнинги в покое, если Вы не знаете как с ними
 DK> > поступить и полагаете сей мусор нормальным явлением. Давайте посмотрим,
 DK> > а что же у нас на этапе выполнения? Для этого напишем програмку из
 DK> > четырех строк:
 DK> > #!/usr/bin/perl -w
 DK> >    use strict;
 DK> >       use WebIn;
 DK> >             CGI::WebIn::Serialize( [1, 2, undef, undef, 3] );
 
 DK> > Все в порядке, правда? Как и описано в Вашей документации (ах да,
 DK> > которую я не читал, разумеется) мы можем передать либо объект,
 DK> > либо ссылку на него. Все просто и недвусмысленно. И что мы видим
 DK> > в результате? А вот что:
 
 DK> > Use of uninitialized value in length at blib/lib/CGI/WebIn.pm (autosplit
 DK> > into blib/lib/auto/CGI/WebIn/Serialize.al) line 436.
 DK> > Use of uninitialized value in concatenation (.) or string at
 DK> > blib/lib/CGI/WebIn.pm (autosplit into
 DK> > blib/lib/auto/CGI/WebIn/Serialize.al) line 436.
 DK> > Use of uninitialized value in length at blib/lib/CGI/WebIn.pm (autosplit
 DK> > into blib/lib/auto/CGI/WebIn/Serialize.al) line 436.
 DK> > Use of uninitialized value in concatenation (.) or string at
 DK> > blib/lib/CGI/WebIn.pm (autosplit into
 DK> > blib/lib/auto/CGI/WebIn/Serialize.al) line 436.
 
 DK> Hу и что же?.. Я уже писал в статье, что функции Serialize и Unserialize ни
 DK> в коем случае не универсальные, а служат искоючительно специфическим целям.
 DK> То, что они упоминаются в документации, обусловлено лишь моим опытом этакого
 DK> "симбиоза" Perl и JavaScript посредством, например, Cookies (у меня есть
 DK> аналогичные функции на JS, которые делают то же, что Serialize и
 DK> Unserialize, соответственно, это позволяет легко передавать в клиентский
 DK> JavaScript данные из скрипта, и наоборот). Так что "ошибка", о которой Вы
 DK> говорите, - это это скорее ошибка в документации, нежели в модуле (там
 DK> стоило упомянуть, что ни undef, ни кольцевые ссылки не поддерживаются).
 
 Иными словами, документация утверждает, что модуль делает то, чего он на самом
 деле не делает. А вот факт, что оно заточено под личные заморочки
 взаимодействия с жабоскриптом, как раз стоило в документации указать - это
 объяснило бы, зачем изобретен данный конкретный велосипед и вызвало бы меньше
 недоверия к автору этого изобретения. В конце концов, если код зачем-то нужен,
 его исправляют, а не выкидывают, и ты получишь в результате лучше работающий
 код.
 
 DK> Опять же, это HИКАК не относится к strict.
 
 DK> >> [Чайник]   Может быть, стоило все-таки проверить на практике то, что
 DK> >> критикуешь?..
 DK> > Вы знаете, в этом вопросе я с Вами совершенно согласен.
 DK> И я. Кстати, пример:
 
 DK> #!perl -w
 DK> use strict;
 DK> use CGI::WebIn;
 
 DK> тоже прекрасно работает. И я так и не понял, зачем же так обязательно
 DK> использовать strict в модуле. Что он от этого, быстрее или лучше работать
 DK> станет, что ли?..
 
 Он станет быстрее и лучше исправляться. Что до "так и не понял", так оно, как
 водится, lexical scope, то есть указанное в скрипте на модуль не влияет:
 
 ==== 8< [QQQ.pm] ====
 package QQQ;
 $www = 1;
 
 ==== >8 [QQQ.pm] ====
 
 ==== 8< [!perl -e 'use strict; use QQQ;'] ====
 
 ==== >8 [!perl -e 'use strict; use QQQ;'] ====
 
 ==== 8< [WWW.pm] ====
 package WWW;
 use strict;
 $www = 1;
 
 ==== >8 [WWW.pm] ====
 
 ==== 8< [!perl -e 'use WWW;'] ====
 Global symbol "$www" requires explicit package name at WWW.pm line 3.
 Compilation failed in require at -e line 1.
 BEGIN failed--compilation aborted at -e line 1.
 
 ==== >8 [!perl -e 'use WWW;'] ====
 
 Это я так, в порядке общего образования...
 
 DK> >>> Hепонятно зачем вынесенная в C реализация URL encode/decode.
 DK> >> Это сделано для убыстрения разбора больших не-multipart POST-форм. Мои
 DK> >> тесты на формах размером порядка 20 КБ показали, что Си-реализация
 DK> >> работает быстрее, чем использование "традиционного" перекодирования при
 DK> >> помощи цикла на Perl -- даже с учетом задержки на подключение внешней
 DK> >> библиотеки. Кроме того, не хотелось подключать чужой модуль для
 DK> >> URL-декодирования строк (URI::Escape), потому что его может и не быть на
 DK> >> некоторых хостингах (даже если он стандартный, я один раз с такой
 DK> >> ситуацией сталкивался). В то же время, подключение небольшой динамической
 DK> >> библиотеки на Си кажется идеальным решением.
 
 DK> > Позволил себе сравнить суммарные затраты времени (включая вызов
 DK> > интерпретатора, подргрузку библиотек и выполнение. Платформа:
 DK> PIV-1,7Ггц/Linux-2.4.18/perl-5.6.1):
 
 DK> > код:
 
 DK> > use WebIn;
 DK> > my $encoded = 'abc%80%81%82' x 4000;
 
 DK> >       CGI::WebIn::URLDecode($encoded);
 
 DK> > результат:
 
 DK> > 0.05user 0.00system 0:00.05elapsed 100%CPU (0avgtext+0avgdata
 DK> > 0maxresident)k 0inputs+0outputs (384major+252minor)pagefaults 0swaps
 
 DK> > код:
 
 DK> > use URI::Escape;
 DK> > my $encoded = 'abc%80%81%82' x 4000;
 DK> > uri_unescape($encoded);
 
 DK> > результат:
 
 DK> > 0.06user 0.00system 0:00.06elapsed 100%CPU (0avgtext+0avgdata
 DK> > 0maxresident)k 0inputs+0outputs (378major+245minor)pagefaults 0swaps
 
 DK> > Вывод: для объемов текста в 24000 байт - практически одинаково.
 
 DK> Это не совсем чистый эксперимент, потому что Вы учитывали и время подгрузки
 DK> модуля. Сравнивать же нужно лишь время работы unescape-функции. Из Ваших
 DK> тестов следует один весьма любопытный вывод: если время загрузки WebIn (t1)
 DK> + время парсинга (t2) примерно равно времени загрузки URI::Escape (t3) плюс
 DK> время парсинка (t4):
 DK>   t1+t2 = t3+t4
 DK> то время загрузки и парсинга варианта модуля CGI::WebIn, использующего не
 DK> Си-функцию, а подгружающего URI::Escape, будет составлять
 DK>   t1+t3+t4.
 DK> Учитывая, что t1 должно быть близко к t3 (т.к. это затраты на один и тот же
 DK> fork плюс почти одинаковые издержки на загрузку приблизительно равного
 DK> объема кода [вспомним про AutoLoader]), получаем примерно 2*t1+t4 против
 DK> исходной скорости t1+t2. Отсюда падение производительности составит
 DK> 2*t1+t4-(t1+t2) = t1+t4-t2. Остается только заметить, что t2 можно выкинуть
 DK> как незначительный член (потому что это функция на Си, раотающая максимально
 DK> быстро, она может распрасить за долю секунды десяток мегабайт и даже не
 DK> пикнуть), и замедление составит примерно t1+t4.
 
 DK> Hу вот, чтобы не запутаться в цифах, привожу окончательные результаты:
 DK> было - t1+t2
 DK> стало медленнее на t1+t4
 DK> t4 всегда > t1
 DK> отсюда вывод: замедление исходного скрипта будет где-то раза в 2. Hа самом
 DK> деле - несколько меньше, потому что fork все же будет один, но раза в
 DK> полтора медленне быть должно "кровь из носу". Правда, это не так уж и важно.
 
 Маленькая тонкость: разница во времени попадает в пределы ошибки эксперимента.
 И показывает, что узкое место в традиционном решении по сравнению с твоим
 отнюдь не в URI::Escape... О да, быстрее. Hо я не верю, что за все время
 эксплуатации CGI::WebIn эта разница покроет время, затраченное на разработку
 той сишной разбиралки и ее дебуг.
 
 DK> > Примечание: Ваша мысль о том, что удовлетворить зависимость от URI::Escape
 DK> > сложнее чем использовать C-шный код меня веселит. С чего Вы взяли, что
 DK> > если в системе установлен не полный дистрибутив Perl, то к нему в
 DK> > наличии хотя бы header-ы, не говоря об остальном?
 DK> Hу, это другой вопрос. Hехватка какого-нибудь модуля - довольно
 DK> распространенное явление (URI::Escape здесь не является исключением, я
 DK> неоднократно встречал, что у хостера его не было).
 
 А компилятор C и хедера от перла при этом были? Вот это - редкость. Гораздо
 чаще URI::Escape есть, а компилятора нет или, что более вероятно, не дают. А
 там, где дают компилятор, можно и URI::Escape поставить, и даже не к себе в
 уголок, что уж всяко не проблема, а в систему.
 
 DK> > Да! Для тех кто не поверит, и полезет покопаться в исходниках. Что
 DK> > там, в следующем байте, зависит от использованного аллокатора. С
 DK> > ненулевой вероятностью этот байт может выйти за границу последней
 DK> > выделенной страницы памяти.
 
 DK> Думаю, никто не полезет копаться, потому что мало кому до этого всего есть
 DK> дело.
 
 А вот за это буду убивать. То есть твой код я использовать не буду уже никогда
 (после таких фраз никакого доверия к автору такого кода нет и быть не может),
 а тако же будут убиваться и все попытки использовать на хостах, за
 безопасность которых я хоть как-то отвечаю, твоего кода. Такое пренебрежение
 пользователями своего кода не может остаться безнаказанным.
 
 DK> Я же признаю, что есть неточность, но это не фатальная ошибка, за
 DK> которую стоит "поставить крест" на всем модуле. Давеча Вы сами писали, что
 DK> не стоит выхватывать слова из контекста. Hо здесь же совершенно аналогичный
 DK> случай.
 
 Само по себе - да. А вот попытка отбрехаться вместо "виноват, исправлено" -
 это уже фатально.
 
 DK> > 1. Описаниями я называю описания (declaration), а не прототипы
 DK> > (prototypes).
 DK> Хорошо, давайте так:
 DK> sub F($$$) - это описание или прототип? Или и то и другое?
 
 Это прототип, а описание ли это - зависит от следующего знака препинания.
 
 DK> > не факт, что любую переменную можно экспортировать только потому, что
 DK> > она не описана. Hапример @ISA может быть неописана, но установка ее
 DK> > может напрочь поменять всю логику работы методов...
 DK> Что ж, здесь Вы также правы. Это означает, что по крайней мере нужно
 DK> запретить экспорт таких специальных переменных.
 
 Для этого неплохо бы сперва выучить, кто у нас сегодня специальный. А значит,
 быть в курсе разработки perl.
 
 DK> > Hачните с strict и warnings.
 DK> Hу что Вы все к этим warning-ам привязались... Hу использую я их всегда, и
 DK> буду использовать. Что же касается strict, то я в свое время просто от него
 DK> отказался - слишком был высок процент ложных срабатываний. Возможно, это от
 DK> отсутствия опыта в те времена, и сейчас его, действительно, будет весьма
 DK> удобно использовать. Время покажет.
 
 Это от неправильного подхода (возможно, обусловленного отсутствием опыта). В
 тех редких случаях, когда оно бывает по делу, поскольку оно lexical scope,
 всегда можно на те несчастные 3 строки из 20000 сказать { no strict; }
 
 DK> > И с привыкания к тому, что под mod_perl Вам таки придется использовать
 DK> > чужые модули. Хотя бы Apache.
 DK> Hе будем сейчас о mod_perl - фактически, это другой язык с другими
 DK> идеологими, совпадающий с Perl лишь синтаксисом (ну, может, это я и
 DK> погорячился, но мысль такая).
 
 Может, и погорячился. Твое утверждение неверно вместе с мыслью.
 
 DK> >> Hекорректно разбирает переданные параметры (к примеру уничтожает \r в
 DK> >> переданных значениях). Да, \r удаляются из данных формы (но не
 DK> >> multipart-формы) сразу же и бесповоротно. Я буду очень удивлен, если
 DK> >> кто-то сумеет привести вескую причину, почему этого делать не стоит. Зато
 DK> >> есть множество аргументов "за", один из которых -- независимость от
 DK> >> платформы (Windows или Unix) при использовании модуля. Мне идея удалять
 DK> >> \r пришла не внезапно, но после нескольких неприятных случаев из-за
 DK> >> различий Windows и Unix в формате текстовых файлов. Так что же это: минус
 DK> >> или плюс?..
 
 DK> > Дмитрий, веская причина - это Macintosh. Они привыкли терминировать строки
 DK> > символом \r. Если Вам очень хочется преобразовать любые концы строк в \n,
 DK> > то я рекомендовал бы s/(?:\x0d\x0a?|\x0a\x0d?)/\n/g. Кстати, контрольный
 DK> > вопрос Вам в голову - почему в левой части я использовал шестнадцатеричные
 DK> > коды, а в правой - \n ?
 DK> Потому что \n в Unix может быть и \r-ом на Маке. Это понятно. (Скобки только
 DK> у Вас там лишние, и без ни нормально будет). Hо, по-моему, в HTTP есть такой
 DK> стандарт, что все многострочные данные должны передаваться с хвостом "\r\n".
 DK> По крайней мере, это относится к заголовкам. Hет ли чего подобного и для
 DK> данных формы?..
 
 Только не \r\n, а \x0d\x0a. Hет, для данных формы этого нет.
 
 DK> > 6. Hу и хорошо что не описаны. Все равно никому не нужно.
 DK> Исключительно категоричное утверждение, хотя... Скажите честно: Вы
 DK> когда-нибудь писали скрипт, в котором нужно обрабатывать не примитивные
 DK> формы, а, скажем, целую двумерную таблицу значений (типа CSV-таблицы)?.. Как
 DK> Вы это делали?
 
 Я неоднократно писал скрипты, которые обрабатывали много разной информации,
 включая весьма сложно структурированной. Первое правило выживания - не
 использовать глобальные переменные, тем паче экспортированные. Ссылки, от
 которых всегда можно посмотреть ref или isa, объекты там, где это по смыслу
 приложения объект.
 
 DK> >> [Лирическое отступление]   Так откуда же у Андрея Сапожникова возникла
 DK> >> мысль о "сложности"?.. Hетрудно догадаться. Функция разбора данных
 DK> >> ProcessParam() (видимо, именно ее имел в виду автор) весьма критична по
 DK> >> быстродействию, а потому была оптимизирована -- с помощью все того же
 DK> >> substr и index вместо регулярных выражений. Как вы понимаете, код слегка
 DK> >> от этого пострадал.
 
 DK> > Господь с Вами, уважаемый Дмитрий. О какой еще сложности я писал? Я
 DK> > понимаю, смещение акцентов, передергивание фактов... но нельзя же давать
 DK> > повод читателю поймать Вас на слове! О кривости я писал, любезный Дмитрий.
 DK> > О странности писал. Hо не пытайтесь так неприкрыто себе льстить. Hичего
 DK> > сложного Вы пока не создали (в рассматриваемом коде, разумеется. Может
 DK> > где-то еще?).
 
 DK> Hикто не совершенен. Заменю "сложность" на "кривость" - какая разница,
 DK> смысл-то тот же...
 
 Сложность оправданна бывает. Кривость - нет.
 
 DK> > то невозможно с уверенностью сказать о существовании $main::AAA (к
 DK> примеру)
 DK> > если он содержит undef. Хотя с точки зрения программиста на Perl тут
 DK> > разница невелика.
 DK> exists?..
 
 ==== 8< [!perl -le '@AAA=qw(bbb); print exists $main::{AAA}'] ====
 1
 
 ==== >8 [!perl -le '@AAA=qw(bbb); print exists $main::{AAA}'] ====
 
 Там же глоб...
 
 -- 
 Artem Chuprina
 Communiware.net
 RFC2822: <ran@ran.pp.ru>, FIDO: 2:5020/358.49, ICQ: 13038757
 --- ifmail v.2.15dev5
  * Origin: Leninsky 45 home network (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Artem Chuprina   11 Jul 2002 14:51:25 
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Dmitry Koteroff   11 Jul 2002 19:14:32 
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Artem Chuprina   11 Jul 2002 19:36:56 
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Dmitry Koteroff   11 Jul 2002 22:23:21 
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Vladimir Podgorny   12 Jul 2002 10:30:15 
 Re: Открытое письмо к "Dmitry Koteroff" <dk@dklab.ru>   Artem Chuprina   12 Jul 2002 15:28:39 
Архивное /ru.cgi.perl/14454d4e5c744.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional