Типаж нужен, чтобы хранить в векторе структуры *разных* типов, все из которых реализуют этот типаж. Гипотетически, Vec<&Eq> — это вектор ссылок на структуры, все из которых умеют сравниваться, но имеют разные типы. На практике что там с чем может сравниться — непонятно, поэтому такой код может и не скомпилируется.
В общем, правило такое: чтобы реализовать типаж для типа в контейнере, этот контейнер должен определять либо тип, либо типаж. Если и то, и другое для него внешнее, то определить реализацию нельзя.
1. Нет, потому что, например, только &ClickCallback содержит указатель на таблицу (это жирный указатель). Насколько я понимаю, ClickCallback как типаж-значение во время исполнения вообще никак не представляется.
2. Внутри одного контейнера (crate) — нельзя, в разных — можно, но придётся импортировать типажи под разными и именами и вызывать не как методы, а как функции.
Поскольку унифицировать можно значение функции с аргументом или, наоборот, аргумент с значением функции, получается интересная модель, которая может «вывести любые недостающие параметры» (если остальных параметров модели для этого хватит).
Прошу не принимать это как оскорбление, но вы идеалист-теоретик :)
Это вы — любитель грязных решений. Я переписал сборку проекта из миллиона строк и тоже знаю, о чём речь.
Смысла в переменных, когда у них одно определение, нет никакого, ибо это не переменные, а константы. Например, при сборке на определённой ОС, определённой версии с определённой библиотекой, добавлять к ключам компиляции такой-то флажок, а с другой библиотекой, другой флажёк и так стопицот раз. Предлагаете каждый флажёк в отдельную переменную пихать, а потом всё слить воедино? А как же тогда стиль? Там не на один экран таких переменных набежит плотным текстом. Поэтому «CFLAGS +=», а вот откуда что пришло уже не так понятно.
Функциональные языки программирования (и, в частности, Haskell) передают привет.
Иммутабельность решает, особенно когда нет областей видимости переменных.
Да, идеальной ситуации «одно определение» не получится всё равно. Но так проще, поэтому надо стремиться к этому.
Про вербоз своими силами — в вашем случае и --dry-run отлично подойдёт. В реальности там будет ещё несколько генераторов генераторов, запуск этих генераторов, несколько кастомных правил, которые делают разные манипуляуции с выдачей генераторов. Генерация и обратобка зависимостей опять же. И разные файлы с разными ключами собираются, конечно же. Ну, то есть всё под одну гребёнку крайне сложно.
--dry-run не подойдёт, потому что он меняет логику. И мы же говорим о журналировании, а не отдельном специальном запуске make. Наличие генераторов генераторов генераторов просто не лучшим образом говорит об архитектуре системы сборки.
И, заметьте, это всё при нормальном код ревью и поставленных процессах. Ибо без них вообще адъ, мрак и средневековье. Я по долгу службы на всякое насмотрелся. Действительно большие проекты всегда живут своей жизнью.
Ну я не спорю, дерьма всегда можно понаписать. Особенно в больших проектах. С Make сделать это несложно.
Поэтому вместо изобретения велосипедов проще взять remake.
Вывод не следует из предпосылок, нет?
В remake всё, что добавлено — отладчик. Это, конечно, позволит попроще жить в уже существующей дерьмовой инфраструктуре, но первопричина в том, что инфраструктура дерьмовая, а не в том, что отлаживаться тяжело. Писать надо так, чтобы отлаживаться не приходилось.
Да, если легаси и всё уже плохо, может и remake поможет. Но вообще это полумера и костыль.
Во-первых, рекомендация про хороший стиль перестают работать.
Очень интересно. Чтобы рекомендации не переставали работать, нужно применять code review.
Во-вторых, там объективная необходимость в переменных, ибо кроссплатформенность и различные настройки и прочее.
Я не предложил отказаться от переменных. Я говорю, что одна переменная — одно определение. Тогда нет необходимости понимать, где же ей было присвоено значение.
В-третьих, в большом проекте может быть много подпроектов, в которых свои мейкфайлы, которые включаются в главный.
You're doing it wrong. В частности, по причине того, что становится сложно отследить определение переменных. Советую почитать эту хорошую статью. Ну и эту, до кучи.
В-четвёртых, в большом проекте вся выдача подавлена — ибо по дефолту выдача нужна только если какие-то ворнинги/ошибки (и это правильно), поэтому отсутствие ключика --всё-равно-всё-печатать-и-не-волнует расстраивает при необходимости копнуть глубже.
Семантика отличается.
make, при наличии в окружении переменных вроде CC и CFLAGS, применит их в процессе компиляции. И файл получится с тем же именем, что и исходник — это проще, когда в одной папке несколько исходников. Как раз при прототипировании.
Ну и мощь — во встроенных правилах:
➜ ls
rpn.y
➜ make rpn
yacc rpn.y
mv -f y.tab.c rpn.c
cc -c -o rpn.o rpn.c
cc rpn.o -o rpn
rm rpn.o rpn.c
Вопрос неявных правил (Implicit Rules) и, в частности, встроенных правил, обойдён, по-моему, незаслуженно. Это распространённый источник недопонимания и желания писать в своих Makefile то, что уже и так встроено в Make.
В качестве отличного источника также рекомендую CMCrossroads (например, Painless non-recursive make) и в частности статьи John Graham-Cumming. Он же автор GNU Make Standard Library — в ней немало хороших решений задач, для которых хотелось бы нагородить своих хаков. И отладчик.
А зачем это может понадобиться?
Поскольку унифицировать можно значение функции с аргументом или, наоборот, аргумент с значением функции, получается интересная модель, которая может «вывести любые недостающие параметры» (если остальных параметров модели для этого хватит).
Это вы — любитель грязных решений. Я переписал сборку проекта из миллиона строк и тоже знаю, о чём речь.
Функциональные языки программирования (и, в частности, Haskell) передают привет.
Иммутабельность решает, особенно когда нет областей видимости переменных.
Да, идеальной ситуации «одно определение» не получится всё равно. Но так проще, поэтому надо стремиться к этому.
--dry-run не подойдёт, потому что он меняет логику. И мы же говорим о журналировании, а не отдельном специальном запуске make. Наличие генераторов генераторов генераторов просто не лучшим образом говорит об архитектуре системы сборки.
Ну я не спорю, дерьма всегда можно понаписать. Особенно в больших проектах. С Make сделать это несложно.
Вывод не следует из предпосылок, нет?
В remake всё, что добавлено — отладчик. Это, конечно, позволит попроще жить в уже существующей дерьмовой инфраструктуре, но первопричина в том, что инфраструктура дерьмовая, а не в том, что отлаживаться тяжело. Писать надо так, чтобы отлаживаться не приходилось.
Да, если легаси и всё уже плохо, может и remake поможет. Но вообще это полумера и костыль.
Очень интересно. Чтобы рекомендации не переставали работать, нужно применять code review.
Я не предложил отказаться от переменных. Я говорю, что одна переменная — одно определение. Тогда нет необходимости понимать, где же ей было присвоено значение.
You're doing it wrong. В частности, по причине того, что становится сложно отследить определение переменных. Советую почитать эту хорошую статью. Ну и эту, до кучи.
Ключик реализуется своими силами элементарно:
make, при наличии в окружении переменных вроде CC и CFLAGS, применит их в процессе компиляции. И файл получится с тем же именем, что и исходник — это проще, когда в одной папке несколько исходников. Как раз при прототипировании.
Ну и мощь — во встроенных правилах:
➜ ls
rpn.y
➜ make rpn
yacc rpn.y
mv -f y.tab.c rpn.c
cc -c -o rpn.o rpn.c
cc rpn.o -o rpn
rm rpn.o rpn.c
Вопрос неявных правил (Implicit Rules) и, в частности, встроенных правил, обойдён, по-моему, незаслуженно. Это распространённый источник недопонимания и желания писать в своих Makefile то, что уже и так встроено в Make.
Насчёт распечатки не понял — Make по умолчанию печататает всё, что делает.
С библиотеками немного более хитро, но сила в минимализме — построить можно что угодно.
Компилятор меняется одной строкой, например, так:
CC=clang make
make -dp --warn-undefined-variables | less
Также, в GMSL есть точки останова, срабатывающие в рецептах целей.
make main
Попробуйте.