1. PHP / Говнокод #23540

    +3

    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
    <?php
     
    class Govno
    {
    	function __toString()
    	{
    		return 'govno';
    	}
    }
     
    ${'<?php'}   = 42;
    ${M_PI}      = 43;
    ${new Govno} = 44;
    ${"\0"}      = 45;
    ${''}        = 46;
    ${null}      = 47;
     
    ${create_function('', 'return null;')} = 444;
    ob_start();
    phpinfo();
    ${ob_get_clean()} = 9000;
     
     
    var_dump(get_defined_vars());

    В ПХП возможно всё, если делать это через жопу.
    https://ideone.com/svS2sO

    Запостил: Stallman, 16 Ноября 2017

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

    • И чем плох "PHP"? Всяко лучше твоего "Python"-а, в котором алгоритм зависит от пробелов-отступов.
      Ответить
      • --PHP лучше чем Python
        --Почему?
        --Потому что в нем алгоритм не зависит от пробелов

        Правда, в PHP он зависит от скобочек...
        Ответить
        • отсутствие скобки (или ";") - синтаксическая ошибка.

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

          надо всех пересаживать на TCL. там все это документированое поведение.
          Ответить
          • >отсутствие отступа - питон съедает, и не давится. и может только потом попозже прога повалится с загадчной ошибкой в странном месте.

            С отсупами проблем только поначалу, первую недельку максимум, а то и всего пару дней. Потом привыкаешь и вероятность наличия ошибок становится нулевой.

            > потому что с контекстами vs локальными/глобальными переменными там просто идиотизм, который никогда уже не будет пофикшен.

            Примеры?
            Ответить
            • > С отсупами проблем только поначалу, первую недельку максимум, а то и всего пару дней.

              пока не пытаешься для какой 3rd party либы дему скопипастить в свой проект.

              > Примеры?

              лень вспоминать. питон несколько месяцев не трогал. типично: структуры управления не создают контекст и переменные как минимум сидят в контексте функции.

              читать глобальные переменные можно всегда - но если пытаешься поменять значение, создает локальную переменную. (или что-то в этом духе. реально не помню. на питоне пишу только копипастя с гугла/SO.)
              Ответить
              • >пока не пытаешься для какой 3rd party либы дему скопипастить в свой проект.
                Таких ситуаций в случае любых языков хватает - код от которого волосы дыбом встают, увы, от языка не зависит.

                > лень вспоминать. питон несколько месяцев не трогал. типично: структуры управления не создают контекст и переменные как минимум сидят в контексте функции.
                Скажем так - у каждого языка есть свои особенности, которые людям его особо не использующим кажутся как минимум странными. Ваши претензии ясны, но как по мне - все это дело привычки.
                В таких случаях, кстати, можно провести аналогию со стадиями принятия неизбежного, даже и менять их не надо. Что то вроде следующего:
                1)Отрицание. Почему не работает код на этом языке? Я же все написал как надо, как привык на другом языке?
                2) Гнев и осознание. Они чертовы извращенцы. Они настоящие психи. Кто придумал эту безумную нелогичную херню?
                3) Торг. А может ну его, этот новый язык. Буду писать, на том, на чем привык. Или все же новый? Ведь он сейчас крутой, популярный.
                4) Депрессия. Я буду писать на новом. Но они все равно чертовы извращены, чтоб им все гореть в аду.
                5) Принятие. Ха, а оказываются эти фичи достаточно сильно облегчают жизнь. А эти недостатки - да я уже про них и забыл. Да и в общем, язык не такой уж плохой, зря я ругался.

                Комментарии - опыт освоения яваскрипта. Стадии - очень условны, четко разделять их так наверное нельзя.
                Ответить
                • > Скажем так - у каждого языка есть свои особенности, которые людям его особо не использующим кажутся как минимум странными.

                  такого рода отмазки питонисты уже используют 10+ лет.

                  но в 3ке начали добавлять type hinting, что говорит что эти отмазки просто бред.

                  > можно провести аналогию со стадиями принятия неизбежного

                  тут я тебе могу даже дать ответ на это:
                  1) "но это же говно!" не есть отрицание.
                  2) "гнев и осознание" ни разу не случались - может быть только в галюцинациях заядлых питонщиков.
                  3) сложно назвать торгом напоминания о том что язык говно.
                  4) "депрессия" - ну наверное только у самих питонистов. но даже гвидо начал из под своего камня вылазить.
                  5) ... я не сомневаюсь что комментарии 10-летней давности к питону 2/3 - которые все были/будут исправлены в питоне 5-6 - будут бросатся в лицо тех кто комментировал, и питонисты будут кричать "ага! принятие!!"
                  Ответить
                  • >> Скажем так - у каждого языка есть свои особенности, которые людям его особо не использующим кажутся как минимум странными.

                    > такого рода отмазки питонисты уже используют 10+ лет.

                    такого рода отмазки %LANGUAGE%исты уже используют %LANGUAGE_AGE% лет.
                    Ответить
                    • тоже верно. зеалотов у всех языков хватает. но некоторые языки - в оссобенности "there is one true way" - привлекают их большее количество.
                      Ответить
                • не хватает цикла в стадиях
                  Ответить
                • > Комментарии - опыт освоения яваскрипта. Стадии - очень условны, четко разделять их так наверное нельзя.
                  Кто Вас заставил JS учить? Почему не отказались?
                  На ГК достаточно много людей ведут себя так, будто их отправили в JS-рабство. Интересно послушать человека, который прошёл этот путь от начала и до конца.

                  Лично мне сразу JS понравился, а python сразу не понравился. И только позже обозначилась пара-тройка неудобных моментов в JS (Нет лямбд, возвращающих поля аргумента; DOM-коллекция - не массив; undefined.x и undefined() не работают вместо того, чтобы возвращать undefined; null и undefined не кастятся в пустую строку; нет аналога мапа для объектов, в объектах не разделяется уровень данных и метауровень, что усложняет использование ассоциативных массивов; return\nvalue возвращает undefined), но общее мнение об этих языках так и не изменилось.
                  Ответить
                  • Изучить заставила работа и необходимость пилить на ней хоть какой нибудь фронтенд. Еще - существующий код на яваскрипте который был ( и увы скорее всего останется) в поддерживаемом мною проекте. Часть этого кода было написано мною некоторое время назад (был молодой, неопытный, задачи требовалось решить как можно быстрее).
                    Ответить
                  • Потом - появилось чуть больше свободного времени, задачи стали чуть менее срочными, начальство без контроля оставило на некоторое время, я начал читать разные статейки в интернете про модные жс фреймворки, появилась необходимость писать новый проект, желание немного осовременить мой код (не совсем правильное слово, но отсутствие тестов в поддерживаемом коде, фронтенд с достаточно монструозным jquery кодом, отсутствие тестовых серверов, не использование гита, развертывание приложений посредством контрол с + контрол + в, иногда через ssh) и отсутствие возможности (частично желания) это сделать. Одна, увы наверное из ключевых причин - "Я увидел красивую игрушку и хочу ее. Хочу и все. Зачем - она красивая, все ее хвалят, я тоже хочу. И не хочу думать нужна она мне или нет, я ее хочу. И вообще я мозгу запрещаю думать на эту тему" (такой я человек временами). Почему мне не сказали нет - обстоятельства и особенности моей работы.
                    Это касаемо почему начал учить. Меня не заставляли, скорее была необходимость решать задачу, была возможность выбрать любой инструмент который захочу. Можно ли было выбрать, что то более подходящее? Не знаю, думаю, что да. Жалею ли я о своем выборе? Немного. Я полез в немного страшные дебри современного яваскрипта, хотя стоило остановиться значительно раньше. Но когда я это понял, было слишком поздно. Я потерял много времени на изучение новой вещи, на исправление ошибок при изучении. В это же время я мог бы написать много полезного кода используюя старую вещь. Это больше всего печалит пожалуй.
                    Ответить
                  • И да - я бы не сказал, что прошел этот путь до конца. Скорее я одной ногой на четверной, а другой на пятой стадии.
                    Из всего того, что бесило в яваскрипте это наверное не нормальная работа с датами (безо всяких там библиотек), отсутствие форматирования строк (сейчас ситуация немного лучше, но все равно не идеал). Самым главным минусом является (уже наверное почти являлась) привычка писать код на питоне и ожидание того, что написаный на яваскрипте код будет иметь такие же принципы работы как и на питоне. А это было далеко не всегда так. В качестве еще одного примера - читать код некоторых библиотек на яваскрипте было адом, по сравнению с тем же действиями с питоновскими библиотеками. С каждым днем использования ситуация становится все лучше, но не слишком быстро.
                    Тех, кто прочитал до конца, прошу данный текст нытьем не считать. Я не считаю, что питон / яваскрипт лучше чем, что либо ( во всяком случае я не хотел этого сказать). Просто захотелось выговориться и сказать, что переходить от использования одного языка к использованию нескольких, некоторым образом отличающихся по работе - сложно.
                    Ответить
                  • >JS (Нет лямбд, возвращающих поля аргумента

                    А можно поподробнее? Такой вариант отработал. Или я не так понял?
                    [1,2,3,4].map(x=>({t: x, tr: x*x, tre: x+'23'}))


                    > в объектах не разделяется уровень данных и метауровень, что усложняет использование ассоциативных массивов

                    https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/for...in ?
                    Ответить
                    • >>JS (Нет лямбд, возвращающих поля аргумента
                      > А можно поподробнее?
                      Р. Кашицын некогда упоминал, что в каком-то языке _.поле были функциями, которые принимали объект и возвращали поле.
                      Если б в JS такое было, можно было бы делать так:
                      > [{x:1},{x:2},{x:3}].map(_.x)
                      [1, 2, 3]

                      (правда, с помощью Proxy можно сделать объект _ с такими свойствами)

                      А вообще, на стыке ООП и ФП JS иногда показывает ерунду.
                      Самое больное - что this не прокидывается автоматически. Уместно было бы сделать 2 варианта получения функции - с привязанным объектом (чтобы работало xs.forEach(console.log) и log имело this=console) и без привязанного объекта, но тогда бы привязывался this вызывающего (например, чтобы не писать var that = this в описании методов, в которых используются какие-то функции, чтобы работало this.xs.forEach(function(x) { if(x < this.y) ... });). Впрочем, вариант с использованием метода без привязанного this надо оставить (чтобы работало [].map.call(myArrayLikeDuck, f)).

                      > for...in
                      Эта штука сломается, если кто-то в своей библиотеке добавил в прототип Object перечисляемую питушню или если мы вдруг своему ассоциативному массиву назначили прототип с перечисляемой питушнёй, а мы хотим только свои поля.
                      Приходится использовать уже for...in с hasOwnProperty и т.п.
                      Но тут-то как раз смешиваются методы ассоциативного массива как объекта (hasOwnProperty) с его ключами как коллекции. Как только кто-то добавит элемент с ключом hasOwnProperty, for...in сломается.
                      Известная мне работающая стратегия (для которой я не знаю контрпримера) - это Object.create(null) + простой for...in.
                      Если я работаю с чужим ассоциативным массивом, мне приходится предохраняться:
                      for(var name in o)
                        if(Object.prototype.hasOwnProperty.call(o, name)) ...

                      hasOwnProperty - чтобы не пролез прототип; hasOwnProperty из Object.prototype - на случай, если в o есть элемент с ключом "hasOwnProperty", не равный Object.prototype.hasOwnProperty.
                      ...
                      Ответить
                      • Спасает только Object.keys(o) + map/forEach, который делает касательно ключей то, что нужно при работе с объектом как с ассоциативным массивом.
                        Но Object.keys(o).map(function(k){ .... k, o[k] ... }) выглядит менее красиво, чем, например, Object.map(o, function(k, v){ .... k, v ... }).
                        Ну и, конечно, хочется какие-то аналоги map, переводящие объект в объект, а также аналоги питоновских +/- для set применительно к JS-объектам.

                        Хотя, это из области общих вопросов не считая дат. С датами в JS, конечно, жуть творится. Особенно "радует", как работают часовые пояса для функций преобразования к обычной строке и к локальной. Я так и не понял юмора, но какая-то из них внезапно может дать результат с использованием перевода часов на летнее/зимнее время, когда другая продолжает переводить без перевода на летнее/зимнее время в том же часовом поясе.
                        Ответить
                        • > Ну и, конечно, хочется какие-то аналоги map, переводящие объект в объект, а также аналоги питоновских +/- для set применительно к JS-объектам.

                          Массив объектов в массив объектов можно. Объект в объект - это уже функции/лямбды пишите.
                          По сложению и вычитанию объектов - сложение частично реализует Object.assign(), но не без нюансов, как я понял.
                          Ответить
                          • > Object.assign()
                            Годно. Хотя, это ECMAScript 2015, в то время как в python a + b давно завезли.
                            Ну и a + b вместо Object.assign({}, a, b), я считаю, было бы красивее. Душа просит перегрузки операторов как в Lua/python.
                            Ответить
                        • >Но Object.keys(o).map(function(k){ .... k, o[k] ... }) выглядит менее красиво

                          too slow
                          Ответить
                      • Про работу с ассоциативными массивами спасибо. Не знал пока всех этих нюансов.
                        > Если б в JS такое было, можно было бы делать так:
                        > > [{x:1},{x:2},{x:3}].map(_.x)
                        > [1, 2, 3]
                        А так не проще?
                        [{x:1},{x:2},{x:3}].map(x=>x.x)
                        Ответить
                        • > Не знал пока всех этих нюансов.
                          Вот в этом и проблема. Простой с виду язык заставляет запоминать кучу ненужной информации.

                          А с приходом новых стандартов всё только усложняется (JS, пока крутится барабан, передаёт привет C++, желает здоровья и счастья и дарит Леониду Аркадьевичу Symbol, сделанный мастерами из его деревни). Вот тот же Symbol можно было бы не вводить, если б разрешили объекты как ключи. Объект всегда уникален - можно смело пихать в общее хранилище свой ключ. А прятать в объекте от его владельцев своё свойство - это какая-то неслыханная подлость :)

                          Те же var и let - торжество изобретательности изголодавшихся по фичам внедрителей фич. Такими темпами в JS будет скоро over18 способов создания переменной (см. 18 оттенков инициализации в C++ по Simon Brand). Теперь надо помнить, какие области видимости у переменных let и var. И это не в C++, а в простом языке, на котором школьники рисуют фотоальбомы на своих домашних страницах. Впрочем, JS и правда не C++, так что могут и убрать лишнее или ввести 'use stricter'.

                          > А так не проще?
                          > [{x:1},{x:2},{x:3}].map(x=>x.x)
                          Проще, чем с function; более универсально, чем _.x, реализованное с использованием прокси.
                          Хотя, глаза всё равно соскальзывают на сиськи возможности как в boost::lambda или http://govnokod.ru/23540#comment394475. С перегрузкой операторов давно бы уже создали lambda.js и пользовались.
                          А, => ещё же и с this по-другому работает.
                          JS за 21 день.
                          Ответить
                          • В общем, нужна какая-то фигня, которая транслируется в JS/другие языки и умеет добавлять пользовательские фичи в язык (диалекты из моих недавних комментариев в каком-то треде).

                            Но важно, чтобы диалекты транслировались в нормальный язык, оставаясь понятными человеку, чтобы не было проблемы, обозначенной, кажется, SemaReal, когда программистам приходилось бы вдаваться в новые чужие диалекты.

                            Соответственно, кулхацкер/математик сможет писать var z = x_i y_i, а обычный человек получит что-то вроде var z = x.map((x_i, i) => x_i * y[i]).reduce((x,y) => x+y); или явный цикл.
                            Ответить
                            • Clojure вроде как умеет? А ClojureScript транслируется в JS.
                              Ответить
                            • > и умеет добавлять пользовательские фичи в язык
                              Где-то вдалеке насторожился и повёл носом лиспер.
                              Ответить
                      • > что в каком-то языке _.поле были функциями, которые принимали объект и возвращали поле.

                        Как минимум в Скала, причём это не только для полей работает, можно писать (_ * _) вместо (x, y) => x * y. Много где есть аналогичный сахар, например, в Clojure #(* %1 %2), CL21: ^(* %1 %2), etc.
                        Ответить
                  • >undefined.x и undefined() не работают
                    Это реально критично, особенно второе?

                    В конце концов ("")(); (1)(); тоже не работает. Так что здесь консистентно.
                    А то что nullы и undefinedы кидают ошибки, так язык ведь не зря называется javascript.

                    > null и undefined не кастятся в пустую строку
                    function ifEmpty(x){return null==x ? "" : x}
                    Ответить
                    • >>undefined.x и undefined() не работают
                      > Это реально критично, особенно второе?
                      Первое вызывает проблемы, когда надеешься более одного раза на то, что несуществующее значение вызывает undefined.
                      var o = {};
                      o.x; // undefined
                      o.x.y; // exception, немного неконсистентно

                      Это поведение добавляет в JS зачатки строгой типизации. Если уж начали отдавать undefined, то продолжайте. Иначе приходится в отдельных случаях писать слишком много проверок.
                      Если нужны строгие проверки и определение уровня, на котором стало undefined, всегда можно явно написать if(o.x && !o.x.y) ..., но нельзя средствами JS избавиться от этой возни, когда важен только позитивный случай (разве что ловить исключения). Подзадолбало немного явно выписывать или городить фигню вида ((options || {})[key1] || {})[key2].

                      Про критичность undefined() сказать точно не могу. Конструкций вида a.b.c().d().e.f() обычно меньше, чем a.b.c.d.e.f.

                      > ifEmpty
                      А в PHP оно в языке сразу...

                      P.S. Очень рад появлению комментариев такого эксперта в интерфейсах языков как Вы. Оказывается, за нами незримо наблюдает Б Пи.
                      Ответить
                      • >Первое вызывает проблемы, когда надеешься более одного раза на то, что несуществующее значение вызывает undefined.

                        Это понятно что оно в динамически тупизируемом язычке лишнее. Но повторюсь, то были ошибки юности, Айк засматривался на жабу.

                        И соглашусь что оно неортогонально (1).x; ("").y;
                        Хотя казалось бы.

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

                        Да ну что вы, какой из меня такой иксперт. Я знаю где-то примерно полтора языка, да то познания о них устарели.

                        А так я зашёл на гк почитать срачик про новый ФФ, написанный на Питухе и немного поунижать крестоблядков.
                        Гк чёто очень упёрто не хочет принимать мой коммент.
                        Ответить
                        • > Да ну что вы, какой из меня такой иксперт. Я знаю где-то примерно полтора языка, да то познания о них устарели.
                          Помню, Вы много говорили про то, что в JS завезли много лишнего, когда я с радостью кушал сладкий хлеб этих фич.
                          А теперь, когда дымка новизны рассеялась, а Вас на ГК почти не стало, я опомнился и прислушался к словам отца-основателя.

                          >>Если уж начали отдавать undefined, то продолжайте.
                          >Согласен, хотя опять-таки иногда полезна ошибка (но это во мне многолетняя привычка говорит).
                          Интересно, можно ли как-то спроектировать язык, чтобы он не стал слишком сложным, но позволял легко и логично (без последствий вроде return\n0;) переключаться между этими двумя режимами. Потому, что они оба полезны в разное время.
                          Ответить
                          • Потрахайтесь еще тут.
                            Ответить
                            • А так я зашёл на гк почитать глобальными переменными там простом языке?
                              Гнев и осознание. Они чертовы извращенцы. Они настоящие психи. Кто придумал эту безумную нелогично. null в PHP приводится предохраняться. Подзадолбало немного полезного кода было написанный на Питухе и немного явно выписывать или городить фигню.
                              Ответить
                              • Всё правильно. Так и есть.
                                Ответить
                              • Я, 3.14159265, находясь в здравом уме и твердой памяти, торжественно заявляю:

                                >Кто придумал эту безумную нелогично
                                Некий юра с гейдева.
                                Ответить
          • >>отсутствие отступа - питон съедает, и не давится
            Конечно же нет.
            def foo():
                print("1")
            print("@")
                print("#")


            print("#")
                ^
            IndentationError: unexpected indent
            Ответить
            • у меня был случай такого типа:
              if a:
                  print("a")
              
              print("b")
              print("с")


              я уже не помню почему, но после пустой строки в блоках (if, циклы, классы), потерялся 1-2 отступа. после того как догадался в чем проблема - починил. но опыт был неприятный.
              Ответить
        • >PHP лучше наPython
          fixed
          Ответить
    • Ав руби тоже можно
      class Fixnum
        remove_method :+
      
        def +(_)
          42
        end
      end
      
      p 2 + 2 # будет 42
      Ответить
      • А в Жабе можно кэш целых питухов (от -128 до +127) подменить.
        Ответить
        • это пул интеджеров, да
          Ответить
        • Угу, можно.

          java -Djava.security.manager

          Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
          at java.security.AccessControlContext.check Permission(AccessControlContext.java:472 )
          Ответить
      • remove_method не обязателен.
        Ответить
    • > ${"\0"} = 45;
      > ${''} = 46;
      > ${null} = 47;
      > ...
      > [""] => int(45)
      > [""] => int(47)

      феерично... никогда бы не догадался что результатат будет таким.
      Ответить
      • На самом деле всё вполне логично. null в PHP приводится к пустой строке, в свою очередь строка с нулевым байтом - это строка с нулевым байтом, просто ideone его нам не показывает. К слову, нулевой байт там есть еще и перед lambda_1.
        Ответить
        • > null в PHP приводится к пустой строке
          Здорово сделано.
          Ответить
          • А ещё true приводится к единице, false к нулю, но ноль к пустой строке. Поэтому на ideone
            <?php
            echo false;
            ?>
            это Standard output is empty
            Ответить
        • > строка с нулевым байтом - это строка с нулевым байтом

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

          нелогично - но работает.

          > К слову, нулевой байт там есть еще и перед lambda_1.

          и это тоже логично? ;)
          Ответить
          • > и это тоже логично? ;)
            Нет, но это настолько глупо, что даже смешно. :3 В остальных случаях работает обычное пыхоприведение к строке. Однако, соглашусь, в случае var_dump() вывод строк "как есть" как минимум бесполезен - ни человеку не прочесть, ни регекспу не распарсить. Хотел было упомянуть здесь var_export(), но выяснилось, что он достоин отдельного говнокода.
            https://ideone.com/gnCKh1
            Ответить
            • > https://ideone.com/gnCKh1

              полный пиздец.

              ЗЫ не могу остановится смеятся. такого пиздеца я давно не видел. если вообще когда-либо видел.
              Ответить
            • Эта функция всё, что можно записать в апострофах, по максимуму записывает в апострофах (потому что кто-то сказал, что апострофы парсятся быстрее, чем кавычки), а то, что не получается, прицепляет в кавычках, но при этом «забывает» упростить выражение и оставляет кучу лишних апострофов?
              Ответить
              • Там, оказывается, чуть-чуть другая история, череду мелких багфиксов упустил, но суть в двух словах такова: http://govnokod.ru/23546
                Шаблонизатор снова сделал мой день.
                А одинарные кавычки, наверное, потому что в сишной строке их эскейпить не надо. :3
                Ответить
    • test
      Ответить

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