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

    −124

    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
    package Exception;
    
    sub new {
       my($package, $what) = @_;
       return bless { what => $what }, $package;
    }
    
    sub what {
       my($self) = @_;
       return $self->{what};
    }
    
    package main;
    
    sub try(&$) {
       my($code, $catch) = @_;
       unless(eval { $code->(); 1 }) {
          local $_ = $@;
          $catch->();
       }
    }
    
    sub catch(&) { $_[0] }
    
    sub throw($) { die $_[0] }
    
    try {
       throw new Exception("Ошибка");
    } catch {
       print $_->what;
    };

    Исключения в perl.

    Запостил: an0nym, 08 Августа 2013

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

    • http://search.cpan.org/~ash/TryCatch-1.003002/lib/TryCatch.pm
      http://search.cpan.org/~doy/Try-Tiny-0.16/lib/Try/Tiny.pm
      http://search.cpan.org/~pjordan/Exception-1.7/Exception.pm
      http://search.cpan.org/~drolsky/Exception-Class-1.37/lib/Exception/Class.pm

      Тысячи их.

      inb4 а изкоробочных - да, нету.
      Ответить
      • "inb4 а изкоробочных - да, нету."

        это слегка неправильно обобщение.

        в перле нету штатного try/catch/finally *синтакса*.

        но его можно самому реализовать.

        все приведеное выше есть чистой воды syntax sugar вокруг `eval {};` (эквивалент `try {}`), `die $smth` (эквивалент `throw smth`) и `if ($@) {}` (эквивалент `catch (e) {}`).

        причина почему не добавляют выделеный синтакс (по крайней мере причина которую я слышал много лет назад) заключается в том что `eval {}` очень медленный и как следствие эксепшены будут весьма заметно тормозить. (и в добавок, только недавно начали реализовывать переменные $@/$!/etc как thread-local. и я не уверен что закончили. в типичном перле это глобальные переменные.)

        вообщем, в перле есть эксепшены, только у них слегка кривой синтакс потому что их реализовали более или менее случайно, и они не рекомендуются потому что подтормаживают (и не поддерживают многопоточность).
        Ответить
        • Нет-нет-нет, реализовать самому != есть в языке из коробки. Понятно, что поверх die и eval можно самому сделать экзепшуны, а на bless построить какой-нибудь Moose с MOP'ом и вот этим всем, но от этого "сделать самому" _в языке_ не появится ни исключений, ни человеческой объектной системы. Оно появится в проектах, которые используют твои (или сторонних разработчиков) наработки, и не более.
          Ответить
          • "Нет-нет-нет, реализовать самому != есть в языке из коробки."

            Но то что занимает 30 строк кода на "реализовать самому" тоже не тянет.

            Я давеча пулы к паре фактори в жабе прикручивал. Официально 0% "реализовал сам" - строго апачевы пулы, но ~200 кода понадобилось.

            Как по мне, я предпочитаю 100% "сделай сам" в 30 строк, нежели чем 0% "сделай сам" но в 200 строк.
            Ответить
            • Дык жава с TOOWTDI никогда не дружила, там каждый под себя няшные оберточки писал. А вот в конкуррентах перлу есть питон, который с ним вполне даже дружит.
              Ответить
            • >> апачевы пулы
              - Предоставляются по умолчанию самим языком, или в виде библиотеки, созданной сторонними разработчиками?
              Ответить
              • Apache Commons, http://commons.apache.org/proper/commons-pool/ -> GenericObjectPool - это то чем у нас на проекте пользуются.
                Ответить
                • >> на проекте пользуются
                  - Но не в языке ведь из коробки. :) Потому и ~200 строк кода. Потому что это "реализовать самому". А вот если бы оно было из коробки - было бы всё как надо.
                  Ответить
                  • Ни один язык/ран-тайм не может предоставлять всего что когда либо может быть кому то где то надо.

                    Единственное что язык может сделать, это позволять расширения в (насколько только возможно) безболезненной и прозрачной форме.
                    Ответить
                    • Что-то лисп недалеко улетел, хотя расширения там весьма приятны...
                      Ответить
                    • Да, но речь не про предоставление языком всего, что только может понадобиться потребителю (разработчику), а про разницу между созданием расширения и предоставлением функционала самим языком из коробки.

                      В случае с перлом и исключениями - исключений из коробки в перле не появляется после создания расширения одним из потребителей языка. И изкоробочных исключений в перле всё ещё нет.

                      Понятно, что в перле самому реализовать исключения - раз плюнуть. И так же просто эту реализацию будет использовать. Но она всё равно получается не более, чем сторонней.
                      Ответить
                    • Всего - нет, но есть языки, которые ближе к этому, а есть те, которые дальше. Есть в яве библиотеки http клиентов, сравнимые по удобству с requests?
                      Ответить
          • eval/if — это и есть изкоробочная штатная реализация try/catch. Из отличий, только синтаксис.
            Ответить
            • Телега - это и есть изкоробочная штатная реализация тачки. Из отличий, 5 км/ч и срет везде.
              Ответить
              • По делу возразить нечего, так будем аналогии кривые подсовывать?
                Ответить
                • Писал уже. Тут предыдущий перлоеб сдулся http://govnokod.ru/13110#comment180432, и можешь дальше почитать по тегу перл.
                  Ответить
                  • Да все аргументы знакомы и сводятся к «мне не нравится» или «мне не привычно». Вот уж удивил.
                    Ответить
                    • Если долго сидеть в вони - можно привыкнуть к запаху.
                      Ответить
                      • Вот ты и привык к какому-то, и теперь другие запахи не милы. Бывает, чё. Только не проблемы Perl или какого другого языка.
                        Ответить
                        • Не-не, ты не дочитал. Я привык, чтобы объявление аргументов функции выглядело как объявление аргументов, чтобы модули работали без магического 1; в конце, чтобы определение классов можно было запомнить, чтобы print (1+2)+3; или выводила 6, или материлась на ошибку. Короче, принцип наименьшего удивления. Так что есть два запаха - перл и не перл. А вам настолько забило нос, что кажется что у перла запах, как и у других языков. Нет, у других языков есть запах, а вот от перла воняет разлагающимся дохлым верблюдом, к которому может подойти только Беар Гриллс, вахахахах!

                          Перл был хорошим языком для того, для чего его задумали - парсинга stdin регулярками и вывода в stdout. Универсальный язык из него вышел вообще никакой.
                          Ответить
                          • Я об этом и написал пару сообщений назад: «не привык» и «не нравится» (#comment192015). Ещё добавилось «не понимаю». Больше тебе добавить нечего к этому. Уныло.
                            Ответить
                            • Устаревшее гавно? Порог вхождения ничем не окупается? "Не такой, как все"?

                              НЕ НУЖЕН
                              Ответить
                              • Это вопрос чисто риторический – трюкачество без меры есть стиль программирования, навязываемый языком PERL.

                                PERL скорее сделает невозможное, чем выдаст сообщение об ошибке. Ваша программа заработает сразу же и будет работать всегда, не вызывая сообщений об ошибках, только насколько правильно – это, как говорится, "тонкий философский вопрос". (Хотя это и к php подходит)
                                Ответить
                              • И вообще, можно, написав любое слово, что придет в голову, поставить символ ";" в конце строки, и это будет считаться правильным выражением/оператором, например так:

                                I_hate_PERL_-_what_a_tricky_language;

                                Секрет прост – слова, не поддающиеся никакой интерпретации, PERL считает строками, заключенными в кавычки, в результате чего получается выражение, а это уже допустимый оператор, о как! Таким образом можно, например, вызвать несуществующую процедуру, просто опечатавшись при наборе ее имени, и потратить много-много часов на отладку неработающего фрагмента – ведь вы не дождетесь от PERL сообщения об ошибке или хотя бы предупреждения ни на этапе компиляции, ни на этапе выполнения, так что ошибку придется искать самостоятельно.
                                Ответить
                                • После этих откровений я начинаю понимать, что за код ты пишешь. Очевидно, про прагму strict ты ничего не слышал, и про прагму warnings — тоже. Только это опять же не проблема языка.
                                  Ответить
                              • Не нужен — не пользуйся. Ты всё более странен.
                                Ответить
                            • Дело даже не в том, что на перле можно написать говнокод. И даже что это проще сделать, чем на других языках. Нормально написанный код на перле смотрится как говнокод!
                              Ответить
                              • На любом языке можно написать говнокод. И возможно, твой код на любом языке смотрится как говнокод.
                                Ответить
                                • >Нет, ты! Нас неопустили совсем! Ко-ко-ко!
                                  При чем тут мой код?
                                  >Нормально написанный код на перле смотрится как говнокод!
                                  Ответить
                                  • А чей код ты тогда оцениваешь как нормальный? Неужели не свой, и нормального кода ты написать не в состоянии?
                                    Ответить
        • Подтормаживать может только eval EXPR, а eval BLOCK парсится единожды и исполняется с той же скоростью, что и любой другой код.
          Ответить
          • давно мерял, но по старой памяти, на 5.6 (или 5.8?): eval EXPR тормозит около 10х и более раз (зависит от выражений внутри), eval BLOCK тормозит около 4х раз. можно попробовать каким Benchmark'ом погонять, но мне лень.
            Ответить
            • Конечно на вызов eval есть накладные расходы. Но они, как правило, не велики по сравнению с временем выполнения остального кода.

              Например:
              perl -MBenchmark=cmpthese -e 'cmpthese(-1, {a => sub { 1 }, b => sub{ eval{ 1 } }})'

              Этот код показывает разницу в 20 раз на Perl 5.14. Однако, если мы добавим в процедуру простейшую арифметическую операцию с переменной, то разница сократится уже до 2-х раз.
              Ответить
              • у меня под рукой только RHEL6.2 на котором древний 5.8.8. с -1 там какой-то баг. с 10млн итераций:
                $ perl -MBenchmark=cmpthese -e 'cmpthese(10_000_000, {a => sub { 1 }, b => sub{ eval{ 1 } }})'
                (warning: too few iterations for a reliable count)
                         Rate     b     a
                b   9708738/s    --  -95%
                a 200000000/s 1960%    --

                с простой функцией разница меньше:
                $ perl -MBenchmark=cmpthese -e 'cmpthese(10_000_000, {a => sub { my ($a,$b) = (20,30); return $a+$b;  }, b => sub{ eval { my ($a,$b) = (20,30); return $a+$b; } }})'
                       Rate    b    a
                b 2341920/s   -- -21%
                a 2949853/s  26%   --

                и на последок:
                $ perl -MBenchmark=cmpthese -e 'cmpthese(10_000_000, {a => sub { eval { 1 } }, b => sub{ eval "1" }})'
                        Rate     b     a
                b   190331/s    --  -98%
                a 12658228/s 6551%    --
                Ответить
                • > с простой функцией разница меньше
                  Ну 20% потерь для такого простого тела это очень даже хорошо. На более-менее сложной функции станет совсем незаметно. А если там внутри этого eval'а какое-нибудь чтение файла, то и совсем в пределах погрешности.

                  А вот eval { 1 } и eval "1" бенчить глупо. Надо на чем-то более-менее реалистичном, чем возврат true. Тогда разница будет поменьше на порядки...

                  P.S. Это я все к чему - если юзать eval во внутренних циклах текстодробилки - да, тормозит. А если для обработки ошибок в каком-нибудь движке для сайта, то 146%, что никакой разницы никто не заметит.

                  > только недавно начали реализовывать переменные $@/$!/etc как thread-local
                  О_о. Т.е. сделали треды, но забыли сделать инфу об ошибках thread-local? Пиздец, приехали. Хотя и в libc когда-то такая же херня творилась с errno. Не учится автор пёрла на чужих ошибках ;)
                  Ответить
    • Обертка к eval & die? Хотел сказать, что перлоебы соснули хуйца, но они его уже лет 10 не вынимают.
      Ответить
    • Чтоооооа? В Perl даже исключений из коробки нет?!
      Ответить
      • Нет конечно. Это же не мейнстрим язык с ООП по Дейкстре, но без каррирования через одно место.
        Ответить
      • Исключения есть. Нет объектной обёртки к ним.
        Ответить
    • Ещё можно сделать разные исключения в такой форме:
      try {
         ...
      } Exc1::catch {
         ...
      } Exc2::catch {
         ...
      };

      Но если бы я запостил столько говна никто бы не стал разбираться.
      Ответить
    • показать все, что скрытоПоссал на питусха
      Ответить
    • показать все, что скрытоССЫКНУЛ НА ПИСТУШКА
      Ответить
    • показать все, что скрытоgovnokod.ru/user/3236 Легендарный очкопитух Дикого Колчана. Шеститонный мочехлёб с ручным разрывом пердака, баттхерто-проецирующий механизм одинарного действия, хотя поить мочой его можно было достаточно быстро, держа хуй левой рукой. Банки объёмом 0.5 литра Мочепоршень. Оснащён боковым стержневым эжектором. У него также есть ещё 2 названия: Писстуханя или Очкописстон. Мочетворец это всего лишь прозвище очкопитуха, ибо там, где он хлебал мочу, она быстро вытекала из его жопы. Перепойка осуществлялась очень просто и со скоростью, на которую способен сам стрелок - ротешник очкописстуха полуоткрывался, открывалась банка мочи, затем заливалась моча и так 6 раз. В конце надо было конечно закрыть рот писстона.
      Ответить
      • Бля, ты бы хоть свечки вставлял, если такой батхерт у тебя. Зажженые, свечки-то.
        Ответить

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