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

    −121

    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
    sub save_info {
        beginTransaction();
         
        #-------    250 строк страшного кода, типа:    ---------
        .....
        goto ERROR if $error_code != 0;
        .....
        
        #-------    или
        if ( $res = save_item($data) ) {
            goto OK;
        }
        ............
           
        #-------    Но конец просто меня убил!!!    ---------  
        OK:
        commitTransaction();
        goto RET;
    
        ERROR:
        rollbackTransaction();
    
        RET:
        return $res;
    }

    Я около 3 лет пишу на perl. И догадывался, что есть perl-программисты, которые используют оператор goto LABEL.
    Но я никогда не думал, что мне придется саппортить их код!!!

    Запостил: antonfin, 13 Августа 2010

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

    • Assembler style, ёпт. Чистейший. Конец особенно.
      Ответить
      • Для ассемблероподобного языка это нормально :)
        Удобно переучиваться на Перл после Ассемблера :))
        Ответить
    • Ничего страшного в goto нет, даже в goto на функцию.
      Надо только пользоваться им в тех случаях, когда он действительно необходим.
      Ответить
      • Не спорю, goto &NAME - довольно распространненая конструкция.
        Поэтому я уточнил в коменте goto LABEL.

        Необходимость использования конструкции "goto LABEL" практически никогда себя не оправдывает (в профессиональном девелопменте я такого точно не встречал).
        Ответить
      • Вы пошутили как бэ?

        Гото нужен только в обном зяыке: в ассемблере.

        В остальных языках он не нужен. Это открыл Дейкстра в 70х.
        Ответить
        • Нужен goto или нет в языках высокого уровня - классическая тема для холивара. К.О.
          Ответить
          • Среди школьников -- возможно.

            Взрослые программисты обычно знают что нехорошо использовать гоуту, глобальные переменные и прочие ужасы
            Ответить
            • Среди кого бы ни было - факт остаётся фактом: это такая же излюбленная тема для однообразных срачей, как "ООП против процедурного стиля" или "нужно ли программисту ВО", и здесь точно так же какие-то новые оригинальные аргументы появляются раз в пятилетку. Это единственное, на что я хотел обратить внимание своим предыдущим постом: всего лишь предлагаю не начинать.
              Ответить
              • Я не могу себе представить человека старше 17ти лет, всерьез доказывающего что гото -- это круто
                Ответить
                • Абсолютно согласен. Никогда не видел кода, где нельзя бы было без этого обойтись, зато видел много кода, превратившегося в кашу. Ну, как минимум, логическую.
                  Ответить
                  • Я тоже так думал, пока не уперся в проблему с многоуровневым меню. Сам старался его обойти, но так и не нашел другого выхода :(
                    Ответить
          • все равно гоуту призрачно с нами... хотя бы в ассме в виде жампов.
            а вот строго ли его запрещать или просто не рекомендовать.... хм
            Ответить
    • А нафига тогда в перле гоуту сделали? Я вот думаю.

      Да и здесь гоуту применено по типу "try" и "catch", а если "try" и "catch" считать нормальным, то и это нормально.
      Ответить
      • Для перла гоуту - это нормально :)
        Ответить
        • не знаю, если в меру, то может и нормально... в любом языке.

          p.s. А сам гоуту не использую.
          Ответить
          • И у каждого эта мера будет своя :)
            Гоуту даже 1 раз уже говно получится. 1 раз не пидарас :))
            Ответить
      • Какой try/catch? Ты что с дуба рухнул? Это классическое кодо-говнище!!!

        О каком try/catch-е идет речь, когда человек пишет goto OK?!?

        Perl-программисты, если им нужна конструкция типа try/catch используют или модуль TryCatch, или более легковесный Try::Tiny.

        Одно дело когда у тебя прерывается выполнение какого-то блока кода из-за непредвиденной ошибки, другое когда скрипт прерывает работу, чтобы найти лейблу и сделать в неё переход.
        Ответить
        • Я сам гоуту не использую. Но я бы оставил этот код.

          Теперь смотри, в try и catch ты можешь сам ошибки выкидывать с помощью команды throw, а не дожидаться, когда произойдет непредвиденная ошибка.

          А теперь внимание!:
          Я скачал исходники перла, питона и пхп.
          Я погрепал файлы с расширением ".c" на наличие оператора goto:

          grep 'goto' `find . -name "*.c"` | wc -l

          Итак
          в Perl`е 1309 гоуту,
          в Python - 3166 гоуту
          в PHP - 16749 гоуту.

          =====
          Так же в википедии написано, что при написании Драйверов, часто юзают goto, потому что у те, кто пишет драйвера, обычно вынуждены использовать только Си, в котором нет try и catch.

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

          ===

          А сам я такого мнения: если можешь написать без гоуту, пиши без него.
          Если не можешь написать без гоуту, всё равно пиши без него.

          Если уж совсем не можешь, то пиши, то пиши с гоуту, но только выпрыгивай из всяких вложенных условий только, и прыгай вперёд, а не назад. ОЧЕНЬ ОСТОРОЖНО в общем надо применять гоуту.
          Ответить
          • А я бы тут goto не оставил бы! Потому как goto LABAL:
            во-первых, запутывает код;
            во-вторых, не является стандартом у perl-разработчиков (более того это считается очень плохой манерой!),
            в-третьих, не существует ситуации, при которой в perl не нашлось бы более адекватного решения (в данном случаи тут можно было заменить goto ERROR и goto OK на return _error( $res ) и return _ok( $res ), где:
            sub _error { rollbackTransaction() shift; }
            sub _ok { commitTransaction(); shift; }
            )

            По поводу try и catch.
            В данном конкретном примере goto не используется как try/catch по причине того, что:
            1) есть конструкция типа "goto OK;" и это не аналог throw.
            2) нет передачи ошибки исключения.
            3) в случаи возникновения действительно непредвиденной ситуации, данный код просто "задается" и скрипт завершит свою работу, то есть не произойдет перехвата исключения.

            Еще раз напомню о том что я имею ввиду perl, возможно в С другая ситуация.
            Ответить
            • ой, блин, хотел отплюсовать, но случайно нажал на минус.
              Прошу извинить меня.
              Ответить
              • Ничего страшного. Вспомнился этот прикол :)
                http://www.youtube.com/watch?v=czoS3DT7Wno
                Ответить
          • Драйверов с Большой Буквы?
            Ответить
            • блин, да что Вы придераетесь. Случайно так написал.
              Ответить
              • приди*раетесь
                Ответить
                • Греп-исследование годное (кстати нет word boundary,
                  echo mugotoba | grep "goto"
                  посчитается за безус-ый переход), но отсылка к педивикии сильно дискредитировала. Серьезно, откуда в педивикии знают как пишут драйвера? Зато суровый и объективный греп там не прокатит. Википедия - не энциклопедия (http://ru.wikipedia.org/wiki/ВП:НЭ)
                  Ответить
                  • >Серьезно, откуда в педивикии знают как пишут драйвера?
                    Может автор статьи сам их пишет? )
                    Ответить
                  • не \bgoto\b, а \sgoto\s чтобы литералы отсечь
                    Ответить
                    • [Python-3.1.2]# grep -P '\sgoto\s' `find . -name "*.c"` | wc -l
                      3163
                      [perl-5.12.2]# grep -P '\sgoto\s' `find . -name "*.c"` | wc -l
                      1275
                      [php-5.3.3]# grep -P '\sgoto\s' `find . -name "*.c"` | wc -l
                      16274
                      Ответить
        • А теперь немного сбавлю назад:
          Из perldoc:

          про goto LABEL
          The author of Perl has never felt the need to use this form of goto (in Perl, that is; C is another matter). (The difference is that C does not offer named loops combined with loop control. Perl does, and this replaces most structured uses of goto in other languages.)
          Ответить

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