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

    −159

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    sub trim
    {
        my ($string) = @_;
        for ($string)
        {
            s/^\s+//;
            s/\s+$//;
        }
        return $string;
    }

    for ($string) такой for ($string)...

    http://ideone.com/JWu2Kt

    Запостил: bormand, 27 Января 2014

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

    • P.S. Это реальный код, который сегодня нашелся в старом скрипте ;)
      Ответить
      • так а что именно не устраивает?
        Ответить
        • for ($string), хотя вполне можно было написать $string =~ регулярка.

          Или это не цикл, а какая-то специальная конструкция, которая означает "помести в $_ аргумент, выполни тело, а потом перепиши $_ обратно в аргумент"?

          Я просто не пойму, каким образом результат попадает в $string. И что вообще такое for ($string), в мане такого случая я не вижу.
          Ответить
          • Все, нашел...
            for VAR (LIST) BLOCK
            1) If VAR is omitted, $_ is set to each value.
            2) If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop.
            3) Лень искать цитату, но строка канает в массивном контексте.

            Блин, за что мне это наказание... Как вы вообще в этом пёрле что-то понимаете...
            Ответить
            • > Как вы вообще в этом пёрле что-то понимаете...

              Мой метод: Глубокий вдох.... Расслабится.... Медленый выдох....
              Ответить
            • > 3) Лень искать цитату, но строка канает в массивном контексте.
              my @arr = ( $string, $string ); # создаем массив

              Так же интерпретируется и внутри for ($string) (т.е. создание массива), ибо можно писать for @array (без скобок)
              Ответить
              • > можно писать for @array (без скобок)
                Да ну? У меня не работает.

                http://ideone.com/dWljKm
                http://ideone.com/gpegXT
                Ответить
                • В первом варианте же написано: syntax error. Сравни:

                  if( 1 ) { print "1"; } # здесь без скобок никак, но:
                  print "1" if 1;


                  Разница в том, что за if или for должно следовать выражение, и без явного выделения скобками в первом случае выражением будет считаться, например, "@a { s/b/d/; }", что ни валидным списком, ни составным выражением для for не является.
                  Ответить
                  • > В первом варианте же написано: syntax error.
                    Спасибо, кэп. Я умею читать логи ;)

                    Т.е. for без скобок можно писать только справа?
                    Ответить
                • Видимо я немного зазнался, только постфиксный вариант
                  http://ideone.com/zqqhEt

                  Ибо вариант for @a { .. code } интерпретатор пытается распознать как hash slice.
                  Ответить
    • Что делает for ($string)? Итерирует по символам?
      Ответить
      • Не, этот цикл выполнит одну итерацию, в пределах которой переменная $_ будет ссылаться на те же данные, что и $string. Ну и регулярки, которые в теле цикла выполнятся, повлияют на сам $string. Я, как не знаток перла, переписал бы так:
        my ($string) = @_;
        $string =~ s/^\s+//;
        $string =~ s/\s+$//;
        return $string;
        Ответить
        • да это же WITH
          Ответить
          • для (строки) {
                убираем левые пробелы;
                убираем правые пробелы;
            }
            Ответить
        • sub trim {
              @_ = @_ ? @_ : $_ if defined wantarray;
              s/^\s+|\s+$//gs for @_ ? @_ : $_;
              wantarray ? @_ : shift
          }


          Итого:

          trim($foo); # модификация $foo
          $bar = trim($foo); # результат в $bar, $foo не меняется
          trim(@foo); # модифицируем строки в массиве @foo
          @bar = trim(@foo); # @foo не меняется, результат в @bar
          Ответить
          • мощно завалил. такими перуэтами я принципиально не пользуюсь.

            а вот это:
            trim(@foo); # модифицируем строки в массиве @foo
            @bar = trim(@foo); # @foo не меняется, результат в @bar

            я как то раз делал чиста по приколу merge sort. есть две возможности: части массива в лоб передавать функции или передавать ссылкой + индексы начала/конца. разница на моих тестах была между двумя методами меньше 15%. после этого перестал извращатся и просто в лоб копирую/возвращаю.
            Ответить
            • > merge sort
              Он же памяти вдвое больше жрет... Это на дисках его юзают от безысходности, а в оперативе зачем?
              Ответить
            • IMHO, тут можно попытаться понять, что и как происходит с аргументами функций :) Разобрался - получи левел ап!
              Ответить
              • @_ = @_ в случае @bar = trim(@foo) это копия, чтобы аргумент не запороть?
                Ответить
              • да там как бы ничего сверхестественного и не делается.

                но я лично по граблям void context vs. list context vs. scalar context уже в доволь находился, и больше не хочется. поэтому я почти никогда wantarray не пользуюсь. как и неявной передачей $_/@_.
                Ответить
        • > Я, как не знаток перла, переписал бы так:

          Я ленюсь и типично пишу: $string =~ s!^\s+|\s+$!!g;

          Слегка менее эффективно, но по барабану, потому что лень правильно писать.
          Ответить
          • Там говорят еще готовый трим был, я хотел выкинуть эту херню из топика и заюзать готовый - но что-то String::Utils в дефолтовой поставке 5.14 не нашелся.
            Ответить
            • документация содержимого дефолтовой поставки проиндексирована вот тут:
              http://perldoc.perl.org

              но для трима никто ничего включать не будет, потому уже делается в одну строку.
              Ответить
    • ох уж этот перл с его дефолтными переменными...
      Ответить

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