"PHP" / Говнокод #16208 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
if (count($vCard) == 1) {
    print_r($vCard -> n);
    print_r($vCard -> tel);
} else {
    foreach ($vCard as $vCardPart)
    {
        print_r($vCardPart -> n);
        print_r($vCardPart -> tel);
    }
}

https://github.com/nuovo/vCard-parser

Ну за каким хуем обрабатывать один элемент как отдельный случай?!

Запостил: bormand bormand, (Updated )

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

  • P.S. Почему матерюсь: если в файле всего одна карточка, то нельзя бежать foreach'ем, а надо сразу лезть в поля. Эталонный пример дырявой абстракции...
    Ответить
    • ну вот пример динамики: элемент может быть как коллекцией, так и самим элементом, если он в ней один.
      это чтобы не городить такие штуки как element->values->value
      Ответить
      • > элемент может быть как коллекцией, так и самим элементом, если он в ней один
        Дурость это неюзабельная, а не пример динамики. По крайней мере в том виде, в котором мы это видим в данной либе.

        > это чтобы не городить такие штуки как element->values->value
        Это прекрасно, но разве так сложно было сделать, чтобы этот сраный один элемент возвращал итератор, возвращающий самого себя? Чтобы людям, которые хотят просто спарсить карточки в цикле не приходилось писать говно из топика... Иначе получается, что штуки типа element->values->value городить не надо, зато надо проверять count на единицу, и обрабатывать этот случай ОТДЕЛЬНО, ну либо юзать весьма неприятный хак с оборачиванием в массив, про который я написал ниже.
        Ответить
        • >элемент может быть как коллекцией, так и самим элементом, если он в ней один.
          Я писал такое как опять-таки оптимизацию.
          Экономия на обжекте-обертке.
          Например есть MultiMap с миллионами данных в котором у ключа может быть несколько значений.
          Но такое бывает редко.
          http://code.google.com/p/memory-measurer/wiki/ElementCostInDataStructures
          LinkedList :: Bytes: 24.00
          Оверхед LinkedLista большой и занимает много памяти (95% одиночных элементов обёрнуты в него), потому проверял instanceofом тип, ну и немного говнологики.
          Правда от конечного пользователя все подобные хаки сокрыты.
          Ответить
          • Ну этот одинокий элемент все равно же поддерживал общий интерфейс, и по нему можно было бегать for'ом, не обращая внимания, на то, что он forever alone? Ведь правда же?

            > Правда от конечного пользователя все подобные хаки сокрыты.
            Во-во.
            Ответить
      • Если выше непонятно объяснил:
        // вот так НЕЛЬЗЯ, либа этого не позволяет
        $cards = new vCard('1.vcf');
        foreach ($cards as $card) {
            // нам похер, сколько там карт, хоть 0
        }
        
        // и даже так НЕЛЬЗЯ, ибо абстракция дырявая как жопа Саши Грей
        // и оператор скобки не перегрузили интерфейс ArrayAccess не реализовали
        $cards = new vCard('1.vcf');
        $n = count($cards);
        for ($i = 0; $i < $n; ++$i) {
            $card = $n == 1 ? $cards : $card[i];
            // работаем с $card
        }
        
        // а нужно так, с блядской проверкой на 1
        $cards = new vCard('1.vcf');
        if (count($cards) == 1) {
            // обрабатываем одну карту
        } else {
            foreach ($cards as $card) {
                // обрабатываем одну из многих карт
            }
        }
        Ответить
          • Ну опять же - это закапывание симптомов вместо лечения болезни.
            Ответить
          • if (!is_array($cards)) $cards=array($cards);

            Есть такие блядские либы которые когда результат 1 возвращают объект а когда больше массив объектов, самое хуёвое, что когда нет результата воpвращают null.
            Ответить
            • > Есть такие блядские либы которые когда результат 1 возвращают объект а когда больше массив объектов
              Это одна из них 🙂

              > самое хуёвое, что когда нет результата воpвращают null.
              Не, эта либа, слава богу, кидает экцепшн. За это автору респект.
              Ответить
              • респект на ексепшн? культура программирования катится в ад
                Ответить
                • > респект на ексепшн? культура программирования катится в ад
                  А что не так с экцепшеном из конструктора?
                  Ответить
                  • ну я думал что это нормальное поведение. а тут за него хвалят, будто это прям вершина. мне кажется за не использование эксепшенов надо наказывать
                    Ответить
                    • > а тут за него хвалят, будто это прям вершина.
                      Ты не забывай, в каком разделе ты находишься... Тут с чистой совестью могли захерачить die, или тупо не обрабатывать ошибку вообще...
                      Ответить
                • > респект на ексепшн? культура программирования катится в ад
                  На днях пописал немного на C# и сжёг стул. Порыться в мешке значений грозит смертью - это какой-то мини-ад.
                  // JS
                  var x = {};
                  ...
                  var str = x["key"]; // ОК, товарищ. Нет значения - будет undefined.
                  if(str === undefined) return null;
                  return func(str);
                  
                  // C#
                  var x = new Dictionary<string, string>(); // string передаётся по ссылке - почему бы не вернуть null?
                  ...
                  string str = x["key"]; // АЗАЗА ТИ ЛАЛКА НЕТ ЗНОЧЕНЕЯ ЭТА ЭСКЛЮЧИТЕЛЬНОЯ СЕТУАЦЫЯ
                  // ЭКЗЕПШАН АШИПКА 0x0005fb68 АЗАЗА Я ТИБЯ ЗАТРАЛЕЛ
                  if(str == null) return null;
                  return func(str);

                  Порадовался "сишному" Dictionary<TKey, TValue>.TryGetValue. Взял переменную, проверил результат - и никаких богомерзких try, catch, скобочек, сломанной структуры кода.
                  Ответить
                    • В JS [] возвратит значение/undefined, в c++ [] возвратит значение или создаст и возвратит (и есть find с понятным мне названием), а вдруг сразу бьют по рукам и названия непонятные. Непривычно.
                      Ответить
                      • ну тут все утыкается в "непривычно" это не страшно
                        Ответить
                      • Самый нормальный вариант - возвращать два значения, одно - значение полученое по ключу, другое - был ли действительно такой ключ.
                        Т.е. ж.скрипт вариант тут лажает, т.как
                        var foo = { foo: undefined };
                        foo.foo === foo.bar;

                        А чтобы узнать а был ли ключ, нужно сделать:
                        "foo" in foo;


                        Я думаю, что соображения выше вместе с типичным поведением массивов при доступе по несуществующему индексу и мотивировали ошибки при обращении к хеш таблице.
                        По личным наблюдениям ошибка при попытке получить значение по несуществующему ключу - как правило бесполезная, попытка записать по невозможному ключу - хоть и не очень приятная, но оправдана, по крайней мере соображениями типа выделения памяти под массивы. Как правило код все равно сломается, если мы ничего не нашли по нужному ключу, ну а если мы эту ситуацию уже предусмотрели, то вообще замечательно.
                        Ответить
                  • > Взял переменную, проверил результат - и никаких богомерзких try, catch, скобочек, сломанной структуры кода.
                    Дык есть же джве ситуации:
                    1) Отсутствие значения - баг в коде (из поля в базе прочиталась херня, которую мы не знаем как обрабатывать). Тут лучше кинуть исключение и обработать его тупо отбоем запроса, закрытием сессии или даже остановкой сервера. Прокидывать коды возврата в таких случаях - противно.
                    2) Отстутствие значения - нормальная ситуация. Тут как раз поможет TryGetValue. Исключения здесь не особо удобны.
                    Ответить
                    • Вот поменять бы местами...
                      [] для нормальных ситуаций, TryGetValue - для багов в коде (по аналогии с гармоничными привычным [...] и длинным at(...)). TryGetValue для меня означает "ну я сейчас попытаюсь взять значение, а если не получится - ловите исключение".
                      Ответить
                      • Ну я привык наоборот - по дефолту эксепшен, а хочешь в обход - вот тебе метод в обход. на вкус и цвет...

                        Говоряят стетор уходит. Как Ельцин
                        Ответить
                        • Я к вольности привык. Чтоб не все расплачивались за ошибку, а в одной функции вылез NaN. Чтоб хотелось замолить свой грех, добавив проверку результата malloc, а не приводить int к bool и не окружать невинные строки слоями try/catch...

                          Хм, жаль, что уходит. Как человек, способный сказать что-то не про программирование, он полезен для сайта. Можно читать только комментарии wvxvw и товарищей на ГК и расширять кругозор.
                          Ответить
                          • Ябм
                            Хорей
                            Дактиль
                            Амфибрахий
                            Анапест

                            Просвещайтесь с Кегданом.
                            А вообще ГК превратился в форум. Порой интереснее просто болтать о всяком, чем обсуждать код. И это хорошо.
                            Ответить
            • > foreach((array)$cards as $card)
              $cards - объект с итератором. Х.з., что там получится после такого каста... Лень тестить, но, имхо, не взлетит.

              > if (!is_array($cards)) $cards=array($cards);
              > foreach(is_array($cards)?$cards : array($cards) as $card)
              Туда же.
              Ответить
  • >Ну за каким хуем обрабатывать один элемент как отдельный случай?!
    Оптимизация же.
    Для малого количества итераций рынарешники вручную анроллят циклы.
    Ответить
    • > Для малого количества итераций рынарешники вручную анроллят циклы.
      Не, я поступил совсем по-читерски:
      // грязный хак
      if (count($cards) == 1)
          $cards = array($cards);
      
      foreach ($cards as $card) {
          // ...
      }
      Ответить
    • switch(count($cards))
      {
          case 0:
              break;
          case 1:
              doShit($cards);
              break;
          case 2:
              doShit($cards[0]);
              doShit($cards[1]);
              break;
          //...
          default:
              foreach ($card as $cards)
              {
                  doShit($card);
              }
      }

      Оптимизировано
      Ответить
  • Типично в таких ситуациях пишут (или берут из библиотеки!) функцию типа
    foreach (ensure_array($whaterver) as $x) { ... }
    и все счастливы.
    Ответить
    • Не упало - значит всё работает.

      P.S. Да не, к либе в целом претензий нет, свою задачу она решает.
      Ответить
        • > а почему не эта либа?
          Да там по задаче надо 2-3 поля из vcard'а выцепить... Поэтому выбирали либу попроще, чтобы можно было прочесть и понять. И либы на 30+ файлов сразу оказались в пролете по этому критерию...
          Ответить
  • Кстати, интересно, за что столько минусов? Просто за мат в подписи? Или кто-то всё-таки считает, что код нормален, и так и надо? Или же код слишком уныл или баянист?
    Ответить

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

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8