Кресты / Говнокод #11549 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  32. 32
#include "xsmell.hpp"
#include <iostream>

TAG(html,  NO_ATTRIBS);
TAG(head,  NO_ATTRIBS);
TAG(title, NO_ATTRIBS);
TAG(body,  NO_ATTRIBS);
TAG(p,     NO_ATTRIBS);
TAG(a,     ATTRIB(href));
TAG(img,   ATTRIB(src), ATTRIB(alt));

int main()
{
    using namespace xsmell;

    document doc = 
        _
        <html>_
            <head>_
                <title>"XSMELL demo"<!title>_
            <!head>_
            <body>_
                <p>"Yesssssssssssssssss!"<!p>_
                <img .src("chucknorris.png") .alt("sneezing eyes open")>_ <!img>_
            <!body>_
        <!html>
        _;

    std::cout << doc << '\n';

    return 0;
}

C++ умеет HTML не хуже этих ваших похапешечек ;)

https://bitbucket.org/edd/xsmell/src

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

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

  • Надо было добавить из readme:

    And you no longer have to worry about generating malformed XML! After spending
    hours fighting obscure C++ compiler errors, you'll be 100% certain that your
    XML is correct.
    Ответить
                • Минус, за то, что вы знаете кто такой
                  > сергей дроботенко
                  .
                  (Я гуглил)
                  Ответить
                  • эх молодёжь пошла
                    которая не знает, что такое аж 2 канала на ТВ в 90-е - орт и ртр
                    я еще коклюшкина помню
                    минусуйте меня
                    Ответить
                    • Вот шельма, настольгические настроения + щепотка самобичевания в виде
                      > минусуйте меня.
                      Да это ж рецепт плюсов!
                      Ответить
                    • В незапамятные времена они так и назывались - Первый и Второй.
                      КАК ВЫ МОГЛИ ЗАБЫТЬ ПЕТРОСЯНА?!
                      Ответить
                          • учитывая черно-белость картинки не поймут не только школьники, но ещё, как минимум, студенты и те, кому до 40.
                            Ответить
                            • Вот вы у каждого человека, кому до 40, возьмите справку, что он не понял. И приходите завтра.
                              Ответить
                            • Мне сильно меньше сорока, но я узнал Мишулина и Держивина, а вообще - этот номер знаю давно. Доктор, я умру?
                              Ответить
                      • слишком банально, петросяна все знают, а качка коклюшкина - единицы
                        петросян тогда в своей "смехопанораме" только и делал, что пи... говорил не по делу, вместо того, чтобы какие-никакие видеобояны демонстрировать,

                        вот квн тогда был огого какой торт, по сравнению с унылым аншлагом
                        а сейчас квн сам уныл
                        Ответить
                        • А Шифрину никто
                                                            не пишет.
                          Коклюшкина никто
                                                            не ждёт.


                          Минусуйте меня за то, что я помню эту пародию.
                          Ответить
                        • Забудешь его как же. Приходят тут некоторые и напоминают.
                          Хоть бы там к примеру поволили бы или по батрутдилили бы на конец. Хотя... все же Петросян круче.
                          Ответить
  • def html = xml <# 
            <html>
              <head>
                <title>$title</title>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
                <link rel="stylesheet" href="http://rsdn.ru/css/article.css" type="text/css" />
              </head>
              <body marginwidth="20" marginheight="20">
                <H1>$title</H1>
                
                <H2 $unless (props.IsEmpty())>Properties</H2>
                <ol $unless (props.IsEmpty())>
                  <li $foreach (p in props)>$(p.Name) : $(p.PropertyType)</li>
                </ol>
                
                <H2 $unless (events.IsEmpty())>Events</H2>
                <ol $unless (events.IsEmpty())>
                  <li $foreach (e in events)>$(e.Name) : $(e.EventHandlerType)</li>
                </ol>
              </body>
            </html>
       #>;

    http://nemerle.org/wiki/index.php?title=XML_literals
    Ответить
    • Scala поддерживает литералы xml
      В List (Common, Clojure) можно строить литералы xml из s-выражений (например, в compile-time), написав несколько несложных макросов.
      Ответить
        • Это используется для разработки веб-приложений на Scala (http://net.liftweb) и Clojure (http://webnoir.org/ compojure) для генерации валидной html-разметки.
          В теории это можно использовать везде, где нужен xml. Представление документов xml в виде лисповых s-выражений имеет для лисперов довольно много преимуществ (генерация кода, поддержка мощных редакторов вроде emacs).
          Ответить
          • Это да, emacs + paredit делают sexp-ы довольно удобными. Иногда даже для graphviz-а использую (s-dot под elisp адаптировал).
            Но с другой стороны дополнительная прослойка (все равно для валидации каждый раз конвертить) тоже не совсем "по бритве".
            Ответить
            • > дополнительная прослойка ... не совсем "по бритве"
              Ну, как-то же надо генерировать xml по данным. Либо использовать левый шаблонизатор, либо какой-то биндер s-выражений (тоже по сути шаблонизатор). В любом случае, использовать s-выражения для представления древовидных структур выглядит очень естественно и соответствует идеологии bottom-up.
              Ответить
          • >> поддержка мощных редакторов вроде emacs

            >> emacs

            Почему-то ответ Романа меня не удивляет.
            Ответить
      • ECMAScript 4 поддерживает литералы точно так же, прямо в коде. Столько головной боли изза этого - собственно, сами себе свинью подложили. До сегодняшнего дня нет ни одного редактора который бы вменяемо мог раскрасить AS3 код, что уж и говорить про всякие гейши с гуглокодами.
        Из всего кода компилятора бОльшую половину занимает парсилка XML (там можно не только XML, но и в скобочках переменные использовать). В итоге, обычный форыч работает естесственно, лучше литералов. Литералы большая часть использует не правильно, или не понимает, как, например и с регулярными выражениями. Вобщем, не нужно это.
        Ответить
        • я тоже считаю, что не стоит примешивать язык разметки в язык общего назначения. из всех возможностей Scala эта, пожалуй, вызывает у меня больше всего сомнений, хоть мне и понятно зачем она там: паттерн матчинг по xml-документам с проверкой типов, хотят привлечь аудиторию из ынтерпрайза, занимающегося в большинстве своём ковырянием xml-ек.

          Сильно сомневаюсь, что эта возможность принадлежит к числу "сложных" (emacs и idea вроде неплохо справляются, хотя хайлайтер emacs иногда серьёзно сбоит, особенно на больших файлах)
          Идея, например, до сих пор не умеет компилять бОльшую часть валидного Scala-кода (даже без xml литералов).
          Ответить
          • В эмаксе сбои могут быть изза того, что по умолчанию для многих форматов используются "конвенции". Например, для Лиспа, если первой в строке стоит отркывающая скобка, то следующее за ней выражение воспринимается как функция, даже без оглядки на то, что скобка может быть внутри комментария или строки. Сделано для того, чтобы когда обновляется часть файла, не нужно было парсить весь, а только до определенного места назад и вперед. Это можно отключить, но работать будет медленнее.
            В js2-mode есть какая-то подсветка и анализ XML, но если его использовать, то работать будет очень медленно. Честно сказать - я не пытался найти ошибки, но судя по тому, что автор бросил это дело...
            Идея, кстати сказать, так же хреново подсвечивает / анализирует AS3. Но что с них взять, если Адобовский билдер тоже лажает.
            Ответить
            • неа, у него на комментах заглючело:
              http://tinyurl.com/textile-parser-968
              из-за инлайн-комментов воспринимал весь следующий код как комментарии. Если убрать инлайн-комменты, всё нормально расцвечивает. Причём воспроизвести на более мелких файлах не получилось 🙁
              Ответить
              • > воспроизвести на более мелких файлах не получилось
                а, нет, получается, если использовать в точности эту строчку
                Ответить
              • Ну так и Гитхаб тоже плохо код покрасил, особенно там, где XML был.
                Я несколько раз брался написать раскраску для AS3, но изза E4X и метадаты, так ни разу до ума и не довел. Всякие яки-бизоны для этого использовать бессмысленно. И это еще и было придумано людьми, которые типа стандарты пишут... :/
                Ответить
          • >паттерн матчинг по xml
            А можете привести пример конструкции на Scala?
            Я тогда попробую нечто подобное на Nemerle, если пойму как работает.
            Ответить
            • банальный пример c потолка:
              <span id="bottom">text</span> match {
                case <upcase>{contents}</upcase> => println contents.toUpperCase
                case n @ <span>{contents}</span> if (n \ "@id" text) == "bottom" => println("BOTTOM: " + contents)
                case <b>{contents}</b> => println("BOLD: " + contents)
              }
              Ответить
              • 1)Первый кейс проверяет на <span id="bottom"><upcase>...</upcase></span> ?
                2)Второй на... я совсем не понял.
                Третий на <span id="bottom"><b>...</b></span>.

                3)Значение {contents} понятно. Оно "выводится". Там например, может быть следующие теги или текст. Я бы тут передавал contents рекурсивно функции самой себе для поиска следующих тегов.
                Ответить
                • Если что, то я Scala первый раз вижу. Просто предположил.
                  Ответить
                • Первый кейс проверяет, что имеем <upcase>text</upcase> и помещаем text в переменную contents.
                  Второй кейс проверяет, что имеем спан с id == "bottom" - наш кейс.
                  Третий - имеем <b>text</b> и аналогично привязываем текст внутри к переменной contents.
                  Перед match может стоять любое xml-выражение
                  Ответить
              • <span id="bottom">text</span>.(
                    localName() == upcase ?
                    trace(text().toUpperCase()) :
                    @id == "bottom ?
                    trace("BOTTOM: ", text()) :
                    localName() == "b" ?
                    trace("BOLD: ", text()) :
                    throw "Don't know what to do!");

                Так это было бы в E4X. Но это хуже, чем записать по-человечески с обычными ифами или свитчем, и кода меньше сгенерируется, и работать будет лучше, и дебажить удобнее.
                Ответить
    • Вообще код топикстартера выглядит удручающе, в отличии от кода выше. Код ОПа поддерживает только строковые литералы, а тот же цикл создать для генерации уже не получится.
      Ответить
    • Статическая проверка на этапе компиляции 😉

      After spending hours fighting obscure C++ compiler errors, you'll be 100% certain
      that your XML is correct.


      P.S. Но на самом деле, конечно, ненужно.
      Ответить
        • Х.з. мне вникать в этот код что-то совсем не хочется. Скорее всего нет.
          Ответить
          • > вникать в этот код что-то совсем не хочется
            правильно, вдруг это заразно
            Ответить
      • Как говорил один OCamlщик: "если это скомпилировалось -- это работает верно"
        Ответить
  • Всем привет!
    type Seg = (Int, Int)
    type Pos = (Int, Int)
     
    f::Bool->Seg->Int
    f a (c,d) = if a then c else d
     
    f1::Pos->Int
    f1 p = f True p
     
    main = print $ f1 (4,5)
    Как сделать так, чтобы этот код не скомпилировался?
    http://ideone.com/Us6Ek
    Хочу, чтобы типы Seg и Pos не совпадали.
    Ответить
    • fold-ами размахиваешь, а не в курсе, что type - это alias.
      (пере)прочитай gentle introduction что ли.
      Ответить
    • Use newtype, Luke.

      Но только там придется явно указывать имя конструктора. Тупо (4,5) не прокатит.
      Ответить
      • P.S. А за что Роману минус вкатали за data? Тоже ведь корректный вариант, и может даже более подходящий, чем newtype...

        data Seg = Seg Int Int
        data Pos = Pos Int Int
        Ответить
        • > А за что Роману минус вкатали за data?
          так это ж HaskellGovno ответил
          Ответить
          • Ну Роман хороший парень. Я ему никогда не ставил минусов. Он всегда подсказывает нубам таким как я, также как и bormand (жаль имени его не знаю 🙁 )...
            Ответить
      • Спасибки посаны. Вы гении.
        http://ideone.com/vyDRD
        data Seg = Seg (Int, Int)
        data Pos = Pos (Int, Int)
         
        f::Bool->Seg->Int
        f a (Seg(c,d)) = if a then c else d
         
        f1::Pos->Int
        f1 (Pos(a,b)) = f True $ Seg(a,b)
         
        main = print $ f1 $ Pos(4,5)
        http://ideone.com/Z1PAn
        newtype Seg = Seg (Int, Int)
        newtype Pos = Pos (Int, Int)
         
        f::Bool->Seg->Int
        f a (Seg(c,d)) = if a then c else d
         
        f1::Pos->Int
        f1 (Pos(a,b)) = f True $ Seg(a,b)
         
        main = print $ f1 $ Pos(4,5)

        Оба метода работают. Но в чем разница?
        Всё ли я сделал оптимально по количеству лишних символов?
        Ответить
          • Спасибо. Очень годный тутор. Возможно я прозрел.
            Только я как то видел где-то
            type Cock a = Time -> a

            a - в данном случае шаблон и можно использовать там любой тип?
            Можно ли в данном случае заменить type на data или newtype?
            Ответить
          • А вот в примере из тутора, там конструктор MakeNatural. Если им воспользоваться, то можно создать не верное натуральное число, например MakeNatural -1
            Как сделать так, чтобы за пределами модуля этот конструктор не был виден. Но в идеале конечно, хорошо бы, чтобы он не не был виден нигде, кроме как в коде
            instance Num Natural where
            ...
            или это хаскеляпроблема, которую не побороть?
            Ответить
            • > Как сделать так, чтобы за пределами модуля этот конструктор не был виден.
              Не эскпортировать из модуля. Там можно при экспорте указать, какие конструкторы будут доступны.
              Ответить
              • Ну а если я не хочу в отдельный модуль класть этот тип, а хочу чтобы вся программа была в одном файле. Как тогда спрятать от неугодного использования этот конструктор?
                Ответить
              • можно еще добавить, что это называет Abstract Data Types (на haskellwiki должно быть)
                Ответить
        • > Всё ли я сделал оптимально по количеству лишних символов?
          В принципе все норм. Но возможен еще такой вариант:
          data Seg = Seg Int Int
          data Pos = Pos Int Int
          
          f :: Bool -> Seg -> Int
          f a (Seg c d) = if a then c else d
          
          f1 :: Pos -> Int
          f1 (Pos a b) = f True $ Seg a b
          
          main = print $ f1 $ Pos 4 5
          Ответить
                • > Ещё data более медлительная и более ленивая, чем newtype.

                  Нет, не всегда. В твоём случае разницы нет:
                  -- Указатель на пару, содержащую два указателя на число
                  newtype Pos = Pos (Int, Int)
                  
                  -- Указатель на пару, содержащую два указателя на число.
                  -- Т.е. никакой дополнительной медлительности нет.
                  data Pos = Pos Int Int
                  
                  -- Адекватный способ: указатель на пару, содержащую числа по значению.
                  -- Раньше требовалось указывать {-# UNPACK #-}, GHC 7.8 распаковывает
                  -- маленькие поля по-умолчанию.
                  data Pos = Pos !Int !Int
                  Ответить
                  • Обсуждение, продолженное через четыре года после начала. Красиво.
                    Ответить
                    • > четыре года после начала

                      Шесть лет, Карл. roskomgovno раскопал тред и поднял в сток, невольно перечитал. Как быстро время летит, вот вроде вчера только было.
                      Ответить
                      • > вот вроде вчера только было.

                        ага, только тогда это было под другими файками
                        Ответить
          • > f :: Bool -> Seg -> Int
            Кстати, а зачем эти сигнатуры функций указывать, если они все равно выводятся автоматически всегда? Это лишняя трата символов в программе.
            Ответить
            • По большей части для документирования 😉 С сигнатурами читать легче.
              Ответить
              • Получается как бы шаблонная функция, если не указывать сигнатуру функции. Функция может адаптироваться под разные типы. А если указать конкретные, то все уже фиксировано. Это хуже.
                Ответить
                • Ну можно ведь не указывать конкретные:

                  map :: (a -> b) -> [a] -> [b]
                  Ответить
                  • Вы правы. Это очень хорошая идея. Как Хаскел отличает шаблонный обобщённый тип от не шаблона? По наличию заглавной буквы в начале имени шаблона?
                    Ответить
                    • Ну, все типы начинаются с заглавной буквы, а типовые переменные - со строчной.
                      Ответить
                    • Вы тут говорите про шаблоны, но это же не шаблоны. В хаскеле шаблонами называется то, что включается директивой {-# LANGUAGE TemplateHaskell #-}. А то, о чем вы говорите, как на самом деле называется?
                      Ответить
            • иногда позволяет компилятору произвездести более производительный код
              Ответить
            • а ещё если накосячишь в реализации, узнаешь об ошибке в типах при определении функции, а не при её использовании
              Ответить
  • Челябинские программисты настолько суровы что пишут ХТМЛ на С++?
    Ответить
  • Кстати, раз уж на то пошло, XML разрешает точки в именах, дефисы и двоеточия (с оговорками), так что, боюсь, что при всем желании... хотя, кто знает, может и можно, но наверное гораздо тяжелее 🙂 А ведь еще есть processing instructions, и комментарии.
    Так что, сенсация: PHP лучше C++!
    Ответить
  • Вот, например, объясните зачем указывать класс?
    member :: (Eq a) => a -> [a] -> Bool
    member y [] = False
    member y (x:xs) = (x == y) || member y xs

    Ведь скомпилируется, что так
    member :: a -> [a] -> Bool
    что с указанием этого класса (Eq a) => . Так зачем это нужно?
    Ответить
    • Птеросня-тред. Пора открывать раковый корпус. Прорекаю погибель, онафему и онафему ещё раз.
      Ответить
      • >Прорекаю погибель

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

            Но вот что-то мне подсказывает, что погибель предрекают...
            Ответить
      • Ну почему это? Многие фразы вполне экплуатабельные, а
        "Тарас крестам не товарищ", так и вовсе шедеврально.
        Ответить
  • Хотел въебать всем по плюсу, но передумал.
    Ответить
  • Мне стишки про гавно понравились. Однажды, друзья, я вам в ответ тоже посвищу целый раздел стихов в куче.
    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

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


    8