1. Perl / Говнокод #4506

    −126

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    sub Tgetent {
        local($TERM) = @_;
        local($TERMCAP,$_,$entry,$loop,$field);
    
        # warn "Tgetent: no ospeed set" unless $ospeed;
        foreach $key (keys %TC) {
    	delete $TC{$key};
        }
        $TERM = $ENV{'TERM'} unless $TERM;
        $TERM =~ s/(\W)/\\$1/g;
        $TERMCAP = $ENV{'TERMCAP'};
        $TERMCAP = '/etc/termcap' unless $TERMCAP;
        if ($TERMCAP !~ m:^/:) {
    	if ($TERMCAP !~ /(^|\|)$TERM[:\|]/) {
    	    $TERMCAP = '/etc/termcap';
    	}
        }
        if ($TERMCAP =~ m:^/:) {
    	$entry = '';
    	do {
    	    $loop = "
    	    open(TERMCAP,'<$TERMCAP') || die \"Can't open $TERMCAP\";
    	    while (<TERMCAP>) {
    		next if /^#/;
    		next if /^\t/;
    		if (/(^|\\|)${TERM}[:\\|]/) {
    		    chop;
    		    while (chop eq '\\\\') {
    			\$_ .= <TERMCAP>;
    			chop;
    		    }
    		    \$_ .= ':';
    		    last;
    		}
    	    }
    	    close TERMCAP;
    	    \$entry .= \$_;
    	    ";
    	    eval $loop;
    	} while s/:tc=([^:]+):/:/ && ($TERM = $1);
    	$TERMCAP = $entry;
        }
    
        foreach $field (split(/:[\s:\\]*/,$TERMCAP)) {
    	if ($field =~ /^\w\w$/) {
    	    $TC{$field} = 1;
    	}
    	elsif ($field =~ /^(\w\w)#(.*)/) {
    	    $TC{$1} = $2 if $TC{$1} eq '';
    	}
    	elsif ($field =~ /^(\w\w)=(.*)/) {
    	    $entry = $1;
    	    $_ = $2;
    	    s/\\E/\033/g;
    	    s/\\(200)/pack('c',0)/eg;			# NUL character
    	    s/\\(0\d\d)/pack('c',oct($1))/eg;	# octal
    	    s/\\(0x[0-9A-Fa-f][0-9A-Fa-f])/pack('c',hex($1))/eg;	# hex
    	    s/\\(\d\d\d)/pack('c',$1 & 0177)/eg;
    	    s/\\n/\n/g;
    	    s/\\r/\r/g;
    	    s/\\t/\t/g;
    	    s/\\b/\b/g;
    	    s/\\f/\f/g;
    	    s/\\\^/\377/g;
    	    s/\^\?/\177/g;
    	    s/\^(.)/pack('c',ord($1) & 31)/eg;
    	    s/\\(.)/$1/g;
    	    s/\377/^/g;
    	    $TC{$entry} = $_ if $TC{$entry} eq '';
    	}
        }
        $TC{'pc'} = "\0" if $TC{'pc'} eq '';
        $TC{'bc'} = "\b" if $TC{'bc'} eq '';
    }

    Гениальный код.

    Запостил: Arigato, 01 Ноября 2010

    Комментарии (58) RSS

    • Несёте возмездие во имя Луны? Ну-ну.
      Ответить
    • термкап руками парсить ... суровые будни Солярочных админов.
      Ответить
    • Мы поняли, что перл вам не нравится, поняли.

      Но повторюсь: "По существу надо, а не потому, что перл не нравится.",
      Надо расписать конкретно почему здесь плохой код, а не постить, потому что perl не нравится.

      Это я не чтоб вам надоесть, это я за чистоту говнокода.
      Ответить
      • А вы не считаете это говнокодом?
        Да хотя бы на тело цикла гляньте:
        do {
        	    $loop = "
        	    open(TERMCAP,'<$TERMCAP') || die \"Can't open $TERMCAP\";
        	    while (<TERMCAP>) {
        		next if /^#/;
        		next if /^\t/;
        		if (/(^|\\|)${TERM}[:\\|]/) {
        		    chop;
        		    while (chop eq '\\\\') {
        			\$_ .= <TERMCAP>;
        			chop;
        		    }
        		    \$_ .= ':';
        		    last;
        		}
        	    }
        	    close TERMCAP;
        	    \$entry .= \$_;
        	    ";
        	    eval $loop;
        	} while s/:tc=([^:]+):/:/ && ($TERM = $1);

        Это не говнокод?
        Ответить
        • плюсанул код, считаю, что в продакшене не надо баловаться "$_", вызывая его явно или неявно.
          Добавь автор явные строки, было бы лучше.
          Ответить
          • явные переменные.
            Ответить
          • Хотя, добавлю: в маленьких блоках map и grеp всё же можно юзать "$_" )). Там это не так страшно.
            Ответить
            • Хорошо, скажу прямо: eval $loop; не смущает?
              Ответить
              • Смущает. Вот это говно.
                Ответить
                • зачем тогда писать "По существу надо, а не потому, что перл не нравится."? было бы это написано на пыхе, тут бы все уже срали кирпичами и было бы +20 минимум.
                  Ответить
          • Не могу согласиться. Это исключительно вопрос стиля и соглашений в рамках проекта.
            Ответить
    • парсить термкам рукам -- глупо. для этого есть Term::Cap.
      Обычно перловики (в отличии кстати от пхпшников) используют готовые модули, коих на CPANе пруд-пруди.
      Так что автор этого кода видимо совершенно не понимал сути перла, наверное он много писал на php.

      Хотя и этот код впринципе читаем.

      зы: интересно, как бы автор переписал этот код на другой прекрасный язык программирования
      Ответить
      • > Так что автор этого кода видимо совершенно не понимал сути перла, наверное он много писал на php.

        Да, я тоже считаю, что автор данного кода не понимал сути перла и специализировался на php. Тем более, что этот код взят из файла lib/termcap.pl, поставляемого вместе с дистрибутивом Perl.

        # $RCSfile: termcap.pl,v $$Revision: 4.1 $$Date: 92/08/07 18:24:16 $
        Ответить
        • Браво, 1992 год, очень актуально.

          ...А теперь открываем исходник и читаем, что написано в комментариях ниже этой самой строчки SVN:

          # This library is no longer being maintained, and is included for backward
          # compatibility with Perl 4 programs which may require it.
          #
          # In particular, this should not be used as an example of modern Perl
          # programming techniques.
          Ответить
          • ...Снова боретесь с ветряными мельницами и считаете всех дурачками?
            Ответить
          • Ну да, и правда браво, если этот кусок говна до сих пор не исключен, а только планируют.
            При этом было интересно наблюдать за реакцией, когда выдвинули предположение, что это php-шник писал :)
            Ответить
            • Перечитайте внимательно: "for backward compatibility".
              Ответить
              • да ладно, не лукавьте - почти ведь все модули написаны в таком стиле.
                Ответить
                • В перле около 500 стандартных модулей. Сколько исходников из этого числа вы прочитали, чтобы утверждать такое?
                  Ответить
                  • что значит "такое"? то что перл "райт-онли" как бы общеизвестный факт. загляните в любой стандартный модуль и вы увидите:
                    - злоупотребление "$_" - ставим галочку.
                    - злоупотребление регекспами - ставим галочку.
                    - предпочтение краткости удобочитаемости - ставим галочку.
                    Ответить
                    • "Такое" относится к утверждению: "написаны в таком стиле"

                      Согласен, "как бы общеизвестный факт".

                      Что касается "галочек", то см: http://oreilly.com/catalog/9780596001735.
                      Ответить
                      • ну да, примерно в таком стиле большинство модулей и написаны. сколько просмотрел? ну где-то с пол сотни случайно выбранных модулей. к чему этот вопрос? вы хотите сказать что оставшиеся 250 написаны кардинально иначе?
                        Ответить
                        • К тому, что сегодняшняя стилистика отличается от стилистики 18-летней давности, а последняя была вполне приемлема для своего времени. Чтобы не быть голословным: сколько из ваших полсотни модулей содержат строковой eval?
                          Ответить
                          • поиск по "eval $" вернул 101 результат. поздравляю.
                            Ответить
                            • Не сходится. Поделитесь, pls, где и как искали.
                              Ответить
                              • Из стандартных модулей:
                                sub validate {
                                    local($file,$test,$warnings,$oldwarnings);
                                    foreach $check (split(/\n/,$_[0])) {
                                	next if $check =~ /^#/;
                                	next if $check =~ /^$/;
                                	($file,$test) = split(' ',$check,2);
                                	if ($test =~ s/^(!?-)(\w{2,}\b)/$1Z/) {
                                	    $testlist = $2;
                                	    @testlist = split(//,$testlist);
                                	}
                                	else {
                                	    @testlist = ('Z');
                                	}
                                	$oldwarnings = $warnings;
                                	foreach $one (@testlist) {
                                	    $this = $test;
                                	    $this =~ s/(-\w\b)/$1 \$file/g;
                                	    $this =~ s/-Z/-$one/;
                                	    $this .= ' || warn' unless $this =~ /\|\|/;
                                	    $this =~ s/^(.*\S)\s*\|\|\s*(die|warn)$/$1 || do valmess('$2','$1')/;
                                	    $this =~ s/\bcd\b/chdir (\$cwd = \$file)/g;
                                	    eval $this;
                                	    last if $warnings > $oldwarnings;
                                	}
                                    }
                                    $warnings;
                                }
                                Ответить
                                • Вот еще одна гениальная функция:
                                  sub assert {
                                      &panic("ASSERTION BOTCHED: $_[$[]",$@) unless eval $_[$[];
                                  }
                                  Ответить
                                  • вот уже чем вам опять так не нравится перл?
                                    Ответить
                                    • При чем тут сам по себе перл? Или вы считаете, что это не есть кусок говна:

                                      foreach $one (@testlist) {
                                      	    $this = $test;
                                      	    $this =~ s/(-\w\b)/$1 \$file/g;
                                      	    $this =~ s/-Z/-$one/;
                                      	    $this .= ' || warn' unless $this =~ /\|\|/;
                                      	    $this =~ s/^(.*\S)\s*\|\|\s*(die|warn)$/$1 || do valmess('$2','$1')/;
                                      	    $this =~ s/\bcd\b/chdir (\$cwd = \$file)/g;
                                      	    eval $this;
                                      	    last if $warnings > $oldwarnings;
                                      	}
                                      Ответить
                                      • совершенно нормальный код.
                                        что Вас смущает? Регулярки?
                                        Ответить
                                      • я считаю, что вы пристали к этому языку как пьяный к радио.

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

                                        именно поэтому появились вопросы:
                                        - "что вас так задело?",
                                        - "зачем вы тратите свое время на разбор стандартных модулей в поисках евалов и черезмеоного использования регеспов?",
                                        - "кому и что вы пытаетесь доказать?"

                                        да, пока только эти три.
                                        Ответить
                                • Это не модуль. Модулем называется другое.
                                  Ответить
                                  • Товарищ просто не знает регулярок, и как только он их видит -- у него начинается баттхард.

                                    Можно подумать что регулярки в его любимом php пахнут как-то иначе
                                    Ответить
                                    • У него разве PHP любимый?

                                      Я думаю, категоричность и необъективность оценок -- следствие... как бы покорректнее выразиться... профессиональной изолированности.
                                      Ответить
                                    • >
                                      Можно подумать что регулярки в его любимом php пахнут как-то иначе

                                      Регулярки в PHP мало чем от перловких отличаются.
                                      Ответить
                              • искал тоталом по *.пм в /либ и подкаталогах.
                                Ответить
                                • Так я и думал, не там искали. В lib и ниже помимо стандартных лежат какие угодно модули, причем часто -- для разных версий Perl-а. На моем хосте, к примеру, там их 1208 штуки А вот если набрать:
                                  grep -r 'eval \$' /usr/lib/perl5/5.8.8/*.pm


                                  поолучится всего 3 результата. И в каждом случае eval абсолютно оправдан. К примеру, в модуле Benchmark.
                                  Ответить
                                  • а я думал, что "помимо стандартных" лежат в \site\lib, не?
                                    Ответить
                                    • ActivePerl для Win32? Если коротко, то -- нет.
                                      Ответить
                                      • он самый.
                                        не знаю что у вас "нет", но у меня стандартные модули лежат именно в \lib. может под стандартными модулями вы понимаете какие-то труЪ красноглазые модули. лично я под стандартными имел ввиду модули идущие в составе дистрибутива.
                                        Ответить
                                        • Ну допустим. Заходим туда:
                                          $ find ./ -name '*.pm' | wc -l
                                          914
                                          $ grep -r 'eval \$' ./*.pm | wc -l
                                          11


                                          11 результатов на 914 файлов. Откуда число 101?
                                          Ответить
                                          • base.pm
                                            Benchmark.pm
                                            Cwd.pm
                                            diagnostics.pm
                                            Errno.pm
                                            Fatal.pm
                                            JSON.pm
                                            SelfLoader.pm
                                            Shell.pm
                                            Thread.pm
                                            threads.pm
                                            version.pm
                                            Win32.pm
                                            ActiveState\ModInfo.pm
                                            ActiveState\Scineplex.pm
                                            Archive\Zip\BufferedFileHandle.pm
                                            Archive\Zip\MemberRead.pm
                                            Archive\Zip\MockFileHandle.pm
                                            Attribute\Handlers.pm
                                            Class\Struct.pm
                                            Compress\Zlib.pm
                                            Compress\Raw\Bzip2.pm
                                            Compress\Raw\Zlib.pm
                                            CPAN\Distribution.pm
                                            CPAN\Distroprefs.pm
                                            CPAN\InfoObj.pm
                                            CPAN\Kwalify.pm
                                            CPANPLUS\Dist\Build.pm
                                            CPANPLUS\Internals\Source.pm
                                            CPANPLUS\Shell\Classic.pm
                                            CPANPLUS\Shell\Default.pm
                                            Data\Dump.pm
                                            Data\Dumper.pm
                                            DBD\Proxy.pm
                                            Devel\Peek.pm
                                            Encode\Alias.pm
                                            ExtUtils\CBuilder.pm
                                            ExtUtils\Install.pm
                                            ExtUtils\Installed.pm
                                            ExtUtils\Packlist.pm
                                            File\CheckTree.pm
                                            File\Fetch.pm
                                            File\Spec.pm
                                            File\Spec\Cygwin.pm
                                            File\Spec\Epoc.pm
                                            File\Spec\Functions.pm
                                            File\Spec\Mac.pm
                                            File\Spec\OS2.pm
                                            File\Spec\Unix.pm
                                            File\Spec\VMS.pm
                                            File\Spec\Win32.pm
                                            HTML\AsSubs.pm
                                            HTML\Entities.pm
                                            HTTP\Status.pm
                                            IO\Dir.pm
                                            IO\Handle.pm
                                            IO\Seekable.pm
                                            IO\Socket\UNIX.pm
                                            List\Util.pm
                                            List\Util\PP.pm
                                            List\Util\XS.pm
                                            Locale\Maketext\GutsLoader.pm
                                            Math\Complex.pm
                                            Module\Build.pm
                                            Module\Build\Base.pm
                                            Module\Build\Config.pm
                                            Module\Build\ModuleInfo.pm
                                            Module\Build\Notes.pm
                                            Module\Build\PodParser.pm
                                            Module\Build\PPMMaker.pm
                                            Module\Build\Version.pm
                                            Module\Build\Platform\aix.pm
                                            Module\Build\Platform\Amiga.pm
                                            Module\Build\Platform\cygwin.pm
                                            Module\Build\Platform\darwin.pm
                                            Module\Build\Platform\Default.pm
                                            Module\Build\Platform\EBCDIC.pm
                                            Module\Build\Platform\MacOS.pm
                                            Module\Build\Platform\MPEiX.pm
                                            Module\Build\Platform\os2.pm
                                            Module\Build\Platform\RiscOS.pm
                                            Module\Build\Platform\Unix.pm
                                            Module\Build\Platform\VMS.pm
                                            Module\Build\Platform\VOS.pm
                                            Module\Build\Platform\Windows.pm
                                            Net\Ping.pm
                                            Net\Telnet.pm
                                            Scalar\Util.pm
                                            Scalar\Util\PP.pm
                                            SQL\Statement.pm
                                            Sub\Uplevel.pm
                                            Term\Cap.pm
                                            Test\Builder.pm
                                            Test\More.pm
                                            Test\Simple.pm
                                            Test\Builder\Module.pm
                                            Text\Diff\Table.pm
                                            threads\shared.pm
                                            Time\HiRes.pm
                                            version\vxs.pm
                                            Win32\TieRegistry.pm
                                            Ответить
                                            • package Module::Build::Platform::Amiga;
                                              
                                              ...
                                              
                                              $VERSION = '0.3607';
                                              $VERSION = eval $VERSION;
                                              
                                              ...


                                              И так почти везде. К алгоритмам это не имеет никакого отношения.
                                              Ответить
                                              • А зачем так делать?

                                                $VERSION = '0.3607';
                                                $VERSION = eval $VERSION;
                                                Ответить
                                                • Первая строка нужна для совместимости с пакетами ExtUtils::MakeMaker, Module::Build и
                                                  Module::Install, где парсеру правильнее давать строку. В то же время, в рантайме номер версии должен быть числом.

                                                  Это необходимо, если версия выглядит как: 0.001_001. Без кавычек парсер установщика неверно проинтерпретирует ее как число 0.001001. Тогда как часть после подчеркивания здесь, по соглашению, является постфиксом, указывающим на девелоперский релиз.
                                                  Ответить
                                              • показать все, что скрыто
                                                $VERSION = '0.3607';
                                                $VERSION = eval $VERSION;

                                                Ну тоже знатное говнецо.
                                                Ответить
                      • > Что касается "галочек", то см: http://oreilly.com/catalog/9780596001735.

                        Что-то не понял, вы спамите тут книжками по перлу за $49.99?
                        Ответить
                        • Вы именуете "спамом" то, что в цивилизованном мире принято называть "ссылкой на первоисточник".
                          Ответить
                          • Ссылкой на магазин? Зачем мне магазин, кинусь сразу заказывать за $49.99? Или давайте ссылку на электронный ресурс, или не давайте вовсе.
                            Ответить
                            • Нет, заказывать не обязательно, достаточно почитать аннотацию ("full description") или посмотреть картинку.
                              Ответить
                              • > достаточно почитать аннотацию ("full description") или посмотреть картинку.

                                Т.е. достаточно глянуть только на обложку книги, как сразу все вопросы, заданные seonull отпадут сами собой?
                                А ну ка, попробую. Смотрю на обложку книги... Вижу: верблюды, Perl... Ясно, рас там Perl, в таком случае вопросы отпадают. ДА и какие тут могут быть вопросы, если это перл :)
                                Ответить
                                • >Вижу: верблюды, Perl..

                                  Точно глянули? А то там не верблюды, а собачка. Ниже текст на три экрана и оглавление, а под ними -- интервью с автором.
                                  Ответить
              • Хотите сказать, что данный модуль писался не перловщиком, а каким-то говно-пэхэпешником? :)
                Ответить
        • в 92м году в перле не было модулей для работы с термкап.
          в 92м году вообще писали немного иначе (поищите сырцы любой программы 1992го года).
          Кроме того этот файл не рефакторят (там написано что no longer being maintained).

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

    Добавить комментарий