metaclass: (Default)
[personal profile] metaclass
Как известно, страшным грехом в современном программировании считаются синдром NIH, изобретение велосипедов и попытки решить уже решенные задачи, а уже нахождение новых задач - страшнейшее богохульство, на уровне осквернения могил и нежелания смотреть олимпиаду по телевизору.
В связи с этим, в своих дотнет-проектах я стараюсь использовать два стандарных инструмента: MSBuild для сборки и t4 для генерации повторяющегося кода.
Так вот, если первый всего лишь содержит мелкие странности (типа считает переменные окружения своими переменными, но не передает автоматически свои обычные переменные, если вызывает сам себя и не содержит внятных средств организации подпроцедур - т.е. области видимости переменных в нем - это ad-hoc ад писанный людьми, которые никогда не читали SICP), то второй - это теоретически правильное, но неудобное при разработке дичайшее безумие.
И я уверен, что аналогичный темплейтер, сделанный на clojure, был бы намного понятнее, нежели "готовое" решение.

Date: 2014-02-15 09:44 am (UTC)
From: [identity profile] bydlorus.livejournal.com
t4 кто-то реально пользуется? Обалдеть.

Date: 2014-02-15 10:01 am (UTC)
From: [identity profile] metaclass.livejournal.com
Я им генерю анемичные классы - ну типа 100500 полей+пропертей, стандарный набор конструкторов (по полям, присвоение из аналогичного объекта), загрузка-сохранение из json/xml, ToString() и прочее такое. Руками одно и то же писать бесит.

Date: 2014-02-15 10:13 am (UTC)
From: [identity profile] bydlorus.livejournal.com
Я лично не сторонник anemic domain model.

Date: 2014-02-15 10:55 am (UTC)
From: [identity profile] metaclass.livejournal.com
А вот это сгенеренное чюдо через partial классы можно расширять.
Т.е. берем анемик класс, добавляем руками поведения в соседнем файле и все заебца.

Date: 2014-02-15 11:03 am (UTC)
From: [identity profile] bydlorus.livejournal.com
А потом выясняется, что DateCreated должно специальным образом работать, т.е. недостаточно тупого get;set; - и как тогда? Хак в генераторе, специальные случаи?

И чисто интересно, что за предметные области, в которых модели можно генерить, а главное что является исходником? База данных что ли?

Date: 2014-02-15 11:44 am (UTC)
From: [identity profile] metaclass.livejournal.com
Людей, у которых DateCreated должно "специальным образом работать" и это вшито в объекте данных, надо запрещать. Потом начинается ебля с сериализацией, обработкой ошибок, отдельными DTO, DAO, прочими временными объектами. Всякого рода интеллект в проперти вообще пихать занятие такое, не очень гуманное.

Исходником для t4 является сам шаблон, код типа:
FieldDesc[] fields = new FieldDesc[] {
new FieldDesc("string","Caption"),
new FieldDesc("int","Level"),
new FieldDesc("string","Reference"),
new FieldDesc("string","Default"),
new FieldDesc("string","Type")
};

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

Date: 2014-02-15 09:51 am (UTC)
From: [identity profile] sleepy-drago.livejournal.com
ну и как мсбилд если надо чтото посложнее скомпилировать релизную конфигурацию солюшна? недавно искал что бы взять готовое - взял нормально-скриптовый язык с модулями и всем всем всем и то получилось пару тыщ строк барахла чтобы к дженкинсу прицепить и все что народ хочет сделать.

Date: 2014-02-15 10:04 am (UTC)
From: [identity profile] metaclass.livejournal.com
Приемлемо. У меня его скрипт вызывается круизконтролом и выполняет сборку софтины, генерацию БД, редеплой сервиса и набор тестов.

Date: 2014-02-15 10:23 am (UTC)
From: [identity profile] sleepy-drago.livejournal.com
меня остановили фишки типа "пойди тудато найди какую версию данных надо качать", "проверь что измененные файлы на компиляции не были обновлены другими", "пойди напиши в текстовый файлик старооккультного формата что ты там пакуешь". То есть вокруг систем типа перфорса и куч говна и палок на батниках регулярно надо тут пару байт прочитать, выделить нужное, послать куда-то. Правда эти все сложности у нас из-за того что мы в гостях у других людей в другой стране и наши билды должны проверяться _до_ заноса в контроль версий.

Date: 2014-02-15 09:54 am (UTC)
From: [identity profile] bydl0coder.livejournal.com
В Т4-то что не так? Он же ничем не отличается от десятков других шаблонизаторов.

Date: 2014-02-15 10:04 am (UTC)
From: [identity profile] metaclass.livejournal.com
С проверкой синтаксиса у него печально.

Date: 2014-02-15 10:20 am (UTC)
From: [identity profile] jakobz.livejournal.com
99% шаблонизаторов - торжество фашизма. В стиле "а давайте дадим дизайнерам ущербный язык, чтобы они лямбд не нафигачили". Мышление одноклеточного менеджера про то как из человека сделать юнит.

T4 в таком ракурсе предстает уже ошибкой третьего порядка - сначала менеджеры-идиоты придумали шаблонизаторы, потом воспитали себе юнитов-дебилов-программистов, которые потом сделали T4 по образу и подобию шаблонизаторов html для юнитов-дебилов, сделанных по ошибке менеджерами-идиотами.

Date: 2014-02-15 11:12 am (UTC)
From: [identity profile] bydl0coder.livejournal.com
Шаблонизаторы нужны для того, чтобы программа была похожа на то, что получается в итоге, т.е. текст. Это удобней, чем DSL, выдуманные любителями лямбд.

Date: 2014-02-15 11:33 am (UTC)
From: [identity profile] jakobz.livejournal.com
Шаблонизаторы не нужны. Написал про это постом: http://jakobz.livejournal.com/238066.html

Date: 2014-02-15 11:38 am (UTC)
From: [identity profile] bydl0coder.livejournal.com
Какие-то у вас другие шаблонизаторы. Обычные - это которые как похапэ, т.е. с удобным синтаксисом для `print(very_long_string)`. Бывает еще ад типа джанги, где все запрещено, и содомия с созданием DOM в хаскелях и прочем таком.

Date: 2014-02-15 11:44 am (UTC)
From: [identity profile] jakobz.livejournal.com
Да не нужны они любые. Джанго - совсем лютый фашизм. Razor тот же - вроде позволяет писать код, но там ад с переключением синтаксиса и полная жопа с передачей шаблона в хелпер.

По факту всегда образуется слой-обертка над этими всеми div-ами и span-ами, и зачем и что в шаблонах надо писать близко к тексту становится совсем непонятно.

Date: 2014-02-15 11:56 am (UTC)
From: [identity profile] bydl0coder.livejournal.com
Да когда как. Встречал и любителей текст писать и тех, у кого в шаблонах никаких дивов-классов не было, одни хелперы. Хорошо, когда шаблонизатор оба подхода поддерживает, как в рельсах, например.

Date: 2014-02-15 12:03 pm (UTC)
From: [identity profile] jakobz.livejournal.com
Моя позиция примерно такая: да, если обезьянам дать гранату - они могут покалечиться. Но я не обезьяна, и мне не нравится что мне по этой отмазке гранату не выдают. И мне не нравится что людей по-умолчанию считают обезьянами.

Date: 2014-02-15 12:06 pm (UTC)
From: [identity profile] bydl0coder.livejournal.com
Так сложно правильную гранату сделать. Я с ходу не представляю даже, какой в сишарпе может синтаксис, для передачи шаблона в хелпер.

Date: 2014-02-15 12:11 pm (UTC)
From: [identity profile] bydl0coder.livejournal.com
В руби передача шаблона в хелпер работает, потому что такой синтаксис, любому методу помимо аргументов из его декларации можно передать еще и функцию. Будет он ее использовать или нет - его дело, но передать можно. Типа такого:
def foo(x)
  # doing stuff
end

foo(10) do
  puts "Some stuff for foo to call"
end

Date: 2014-02-15 10:01 am (UTC)
From: [identity profile] berezovsky.livejournal.com
"Был недоволен т4 и написал плагин к студии на кложуре".

Date: 2014-02-15 10:13 am (UTC)
From: [identity profile] jakobz.livejournal.com
Вот это вот любимое мое про msbuild. TLDR: во всех студиях инкрементальный билд отключен грязным хаком

    
  <!--
    ================================================================
                                        _ComputeNonExistentFileProperty

    There are certain situations in which we want to always run the CoreCompile target (and
    thus the Csc task), even if the timestamps of the outputs appear to be up-to-date on disk.
    If we're inside the IDE during design-time, then the Csc/Vbc/Vjc task is simply being used to
    initialize the host compiler, so we always want to run it.  Also, if we're inside the IDE, and
    the host compiler is responsible for doing the compilation during an actual build, we want to let
    the host compiler determine whether the output is up-to-date, because there may be source files
    in the IDE's in-memory buffers that we don't know about.

    So, we always run the CoreCompile target if we're in the IDE, and either we're in design-time or
    we're delegating to the host compiler for the actual build.

    We compare against BuildOutOfProcess != true because we cannot assume that the build process will 
    have set BuildOutOfProcess to true or false. Therefore the default behavior should be to do the 
    legacy behavior seen before BuildingOutOfProcess was introduced if the property is not set.
    ================================================================
    -->
  <Target
      Name="_ComputeNonExistentFileProperty"
      Condition="('$(BuildingInsideVisualStudio)' == 'true') and ('$(BuildingOutOfProcess)' != 'true') and (('$(BuildingProject)' == 'false') or ('$(UseHostCompilerIfAvailable)' == 'true'))">

    <PropertyGroup>
      <NonExistentFile>__NonExistentSubDir__\__NonExistentFile__</NonExistentFile>
    </PropertyGroup>

  </Target>

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 9th, 2025 11:01 pm
Powered by Dreamwidth Studios