|
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) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.cgi.perl/14454d4e5c744.html, оценка из 5, голосов 10
|