Отступ для генерации кода - PullRequest
5 голосов
/ 20 октября 2008

Часто программисты пишут код, который генерирует другой код.

(Технический термин - метапрограммирование , но он встречается чаще, чем просто кросс-компиляторы; подумайте о каждой веб-странице PHP, которая генерирует HTML, или каждый файл XSLT.)

Одной из проблем, с которыми я сталкиваюсь, является разработка методов, гарантирующих, что и рукописный исходный файл, и сгенерированный компьютером объектный файл имеют четкие отступы для облегчения отладки. Эти две цели часто кажутся конкурирующими.

Я считаю это особенно сложным в комбинации PHP / HTML. Я думаю, это потому, что:

  • В исходном файле иногда больше HTML-кода, чем генерирующего PHP
  • Файлы HTML, как правило, длиннее, чем, скажем, операторы SQL, и требуют лучшего отступа
  • HTML имеет функции, чувствительные к пробелам (например, между тегами)
  • В результате HTML становится более общедоступным, чем операторы SQL, поэтому требуется больше усилий для разумной работы.

Какие методы вы используете для решения этой проблемы?

<ч /> Изменить: Я принимаю, что есть по крайней мере три аргумента, чтобы не потрудиться генерировать красивый HTML-код:

  • Увеличена сложность генерации кода.
  • Не имеет никакого значения для рендеринга браузером; разработчики могут использовать Firebug или аналогичный, чтобы хорошо его просматривать.
  • Незначительный удар по производительности - увеличено время загрузки пробельных символов.

Я, конечно, иногда генерировал код без учета отступа (особенно SQL).

Однако есть несколько аргументов, выдвигающих другой путь:

  • На практике я нахожу, что я делаю часто читающий сгенерированный код - дополнительные шаги для доступа к нему неудобны.
  • У HTML есть некоторые проблемы с чувствительностью к пространству, которые иногда кусаются.

Например, рассмотрим код:

<div class="foo">
    <?php
        $fooHeader();
        $fooBody();
        $fooFooter();
    ?>
</div>

Понятнее, чем следующий код:

<div class="foo"><?php
        $fooHeader();
        $fooBody();
        $fooFooter();
?></div>

Однако он также имеет различный рендеринг из-за пробелов, включенных в HTML.

Ответы [ 8 ]

4 голосов
/ 20 октября 2008

В более общем случае я написал XSLT-код, который генерирует код интерфейса базы данных C ++. Хотя сначала я пытался вывести правильно код с отступом из XSLT, это быстро стало несостоятельным. Мое решение состояло в том, чтобы полностью игнорировать форматирование в выводе XSLT, а затем запустить полученную очень длинную строку кода через GNU indent . В результате получился разумно отформатированный исходный файл C ++, подходящий для отладки.

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

3 голосов
/ 20 октября 2008

Создайте AST, затем просмотрите его и отправьте исходный код, который правильно отформатирован.

3 голосов
/ 20 октября 2008

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

например, в Python, генерируя больше Python.

def generateWhileLoop(condition, block, indentPrefix = ""):
    print indentPrefix + "while " + condition + ":"
    generateBlock(block, indentPrefix + "    ")

В качестве альтернативы, в зависимости от моего настроения:

def generateWhileLoop(condition, block, indentLevel = 0):
    print " " * (indentLevel * spacesPerIndent) + "while " + condition + ":"
    generateBlock(block, indentLevel + 1)

Обратите внимание на предположение, что condition - это короткий фрагмент текста, который помещается на той же строке, а block - на отдельной строке с отступом. Если этот код не может быть уверен в том, нужно ли добавлять отступы для подпунктов, этот метод начинает падать.

Кроме того, этот метод не так полезен для добавления относительно небольшого количества PHP в HTML.

[Изменить, чтобы уточнить: я написал вопрос, а также этот ответ. Я хотел посеять ответы одним методом, который я использую и который иногда полезен, но этот метод не помогает мне при обычном кодировании PHP, поэтому я ищу другие подобные идеи.]

2 голосов
/ 20 октября 2008

Я обнаружил, что лучше всего игнорировать отступы во время генерации. Я написал общий механизм «форматирования кода», который обрабатывает весь выведенный код. Таким образом, я могу определять правила отступа и правила синтаксиса кода отдельно от генератора. Это разделение имеет явные преимущества.

1 голос
/ 20 октября 2008

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

1 голос
/ 20 октября 2008

Я согласен с странным ответом.

Иногда лучше решить проблему, перевернув ее. Если вы обнаружите, что генерируете много текста, подумайте, не проще ли написать текст в виде шаблона с небольшими кусочками интеллектуального кода генерации. Или, если вы можете разбить проблему на ряд небольших шаблонов, которые вы собираете, а затем сделать отступ для каждого шаблона в целом.

0 голосов
/ 20 октября 2008

В ситуации PHP / HTML я стараюсь, чтобы каждый фрагмент кода был последовательно с отступом в исходном коде. Это делает код читаемым там, где это действительно важно, и обычно имеет побочный эффект создания вывода HTML, который читается. Как уже говорили, firebug позаботится обо всем остальном.

0 голосов
/ 20 октября 2008

Специально для генерации HTML - почему это важно?

Вы тратите много времени на обдумывание параметров отступа и пытаетесь выяснить, насколько глубоко вы вложены и т. Д. Помимо общей траты времени (поскольку в окончательном рендеринге нет разницы) вывод), как вы поддерживаете все эти вещи, когда добавляете другие HTML-разметки и переносите страницы в div и т. д.?

В любом случае, установите Firebug панель инструментов разработчика IE для последующего тестирования IE), и они оба отображают HTML-код во вложенном формате, И вы можете просто нажать на элемент страницы непосредственно просматривать разметку - ПУТЬ более эффективно, чем смотреть исходный HTML-вывод.

...