1. Java / Говнокод #13246

    +73

    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
    public static Rectangle2D fit(final Rectangle2D in, final Rectangle2D out) {
    		final Rectangle2D.Double fit = new Rectangle2D.Double();
    		if (in.getWidth() > in.getHeight()) {
    			fit.width = out.getWidth();
    			fit.height = (out.getHeight() * in.getHeight()) / in.getWidth();
    			fit.x = out.getX();
    			fit.y = out.getY() + ((out.getHeight() - fit.height) / 2);
    		} else {
    			fit.width = (out.getWidth() * in.getWidth()) / in.getHeight();
    			fit.height = out.getHeight();
    			fit.x = out.getX() + ((out.getWidth() - fit.width) / 2);
    			fit.y = out.getY();
    		}
    		// if ((in.getWidth() / in.getHeight()) != (fit.width / fit.height)) {
    		// throw new RuntimeException();
    		// }
    		// if (!fit.contains(fit)) {
    		// throw new RuntimeException();
    		// }
    		return fit;
    	}

    #14-19 - инлайн тесты!
    а вы говорите - юнит-тесты...

    Запостил: Lure Of Chaos, 27 Июня 2013

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

    • фикс:
      # 17: // if (!out.contains(fit)) {
      Ответить
    • Паттерн Commentable Assertion.
      Ответить
      • Надо раскомментарить и обернуть в if (ENABLE_INLINE_TESTS).
        Ответить
        • А что, в Жабе нет #ifdef'ов?
          Ответить
          • зато в жабе есть // if ()
            Ответить
            • >if (ENABLE_INLINE_TESTS)
              в жабе есть assert который никогда не работает.
              Ответить
              • > который никогда не работает.
                Почему?
                Ответить
                • Потому что говно. Или кривые руки. -ea надо писать.
                  Ответить
                  • Работа assert зависит от ключей, переданных команде java при запуске.

                    Потому и не использую.
                    Ответить
                    • Ну а ассерт всегда был не более чем инструментом для отладки. В релизных сборках он и в си\крестах не работает.
                      Ответить
          • В Жабе не нужен #ifdef. Компилятор и так удаляет мёртвый код, в том числе обёрнутый в if (константное_выражение_равное_false).

            То же самое в современных Си-компиляторах. #ifdef нужен был в доисторические времена, когда компиляторы были тупыми.
            Ответить
            • public class TypeSafeMatcher<T>
              #ifdef USE_GUAVA
                implements Predicate<T>
              #endif
              Ответить
              • public class TypeSafeMatcher<T> maybeimplements Predicate<T>
                Ответить
              • Не нужны такие сишкоизвращения. На тёмную сторону дорогой прямой ведут они.

                Если это приложение - вы уж или используйте Guava, или нет. Если это библиотека - добавляйте Guava как жёсткую зависимость, да и всё.

                Кстати, конкретно эта задача решается вообще просто:

                public class GuavaTypeSafeMatcher<T> extends TypeSafeMatcher<T> implements Predicate<T> { }
                Ответить
                • Как раз такой подход совершенно ничего не решает, ибо не позволяет использовать гуавовские функции над предикатами с матчерами.
                  Ответить
                  • Как это не позволяет? Просто используйте нужный подкласс.

                    Не хотите делать для каждого класса подкласс - сделайте статический метод, который будет возвращать реализацию интерфейса через duck typing и reflection.
                    Ответить
                    • Думаю, в реальной жизни нужна скорее конвертация предикатов в матчеры (если приложение уже использует предикаты, писать их клоны для матчеров будет тоскливо). Для этого можно будет написать фабрику адаптеров, убивает весь профит от использования флюент интерфейса матчеров. Пример с препроцессором тут действительно надуманный, ибо он тут не особо поможет.
                      Поможет только наличие стандартных функций (и проектирование библиотек с использованием таких функций), или, на крайняк, имплиситы из скалы.
                      Ответить
              • А что, кроме религии, мешает юзать препроцессор от си в жабе? ;)
                Ответить
                • не приспособленная для этого инфраструктура
                  Ответить
                • Аннотации - по сути препроцессор.

                  Та блядь, написал ответ - а сайт с эксептом свалился.
                  Ответить
                  • аннотации и препроцессор - это вообще очень разные вещи
                    Ответить
                    • Аннотации модифицируют то ли текст, то ли AST перед конпеляцией. В чем такая уж разница? Их писать просто гораздо тяжелее.
                      Ответить
                      • ничего они не модифицируют. они - просто метаинформация. а вот уже обработчики аннотаций на этапе компиляции или выполнения делают с кодом, основываясь на информации в этих аннотациях, что хотят.
                        Ответить
                      • бОльшая часть аннотаций - это просто произвольная метаинформация, доступная на этапе выполнения (retention policy=runtime у 90% аннотаций).

                        Процессоры compile-time аннотаций тоже не имеют отношения к препроцессору, ибо работают на уровне деклараций, а не токенов, это совершенно другой уровень. Например, нельзя изменить синтаксис языка.
                        Ответить
                        • > работают на уровне деклараций, а не токенов
                          насколько я помню, в сишке препроцессор работает на уровне исходного текста по принципу "найти и заменить", еще до лексического разбора - так что еще токенов там нет
                          Ответить
                          • я имею в виду токены самого препроцессора
                            Ответить
                            • да, они обрабатываются безусловно и потом теряются
                              Ответить
                          • не совсем так
                            препроцессор для макроса со скобками должен проверить, что это действительно макрос со скобками (отличить max(... от _max(... и от (max)(... ), проверить число аргументов, вызвать макросы в новом тексте и т.д.
                            так что простейший разбор на токены там есть
                            Ответить
                        • >нельзя изменить синтаксис языка.
                          Это важно?
                          Ответить
                          • Да.

                            Понимаешь разницей между обработкой абстрактного сферического текста ПЕРЕД вызовом компилятора и обработкой языковой структуры, СОЗДАННОЙ компилятором?
                            Ответить
                            • зато можно заюзать, например, АОП, с помощью какого-нить ASM или Javassist
                              Ответить
                            • Сферического-хуического. Зато не будет сишних приколов "как написать шаблон, чтобы он в любом контексте работал и не глючил".
                              Ответить
                              • Я не говорю, что аннотации ХУЖЕ препроцессора. Это просто вещи, служащие для совершенно разных целей. Одно не заменяется другим.
                                Ответить
                                • Отлично, нахуя нужен сишный препроцессор? Что он может, чего не могли бы в принципе сделать аннотации, и стоит ли это делать таким образом?
                                  Ответить
                                  • аннотации умеют в генерацию кода?
                                    Ответить
                                    • @defecate-plusplus вроде как да.
                                      Ответить
                                    • > аннотации умеют в генерацию кода?
                                      Аннотации сами по себе - нет. Это просто заметки, пристегнутые к соответствующим точкам кода.

                                      А вот annotation processor, подключенный к компилятору, уже может сделать все что угодно - и генерацию, и дегенерацию, и перехуяцию.

                                      Ну и в рантайме можно почитать эти аннотации, и воспользоваться ими в своих грязных целях.
                                      Ответить
                                      • ну вот как раз взять романов пример - надо либо наследоваться, либо не наследоваться
                                        это можно сделать аннотациями?
                                        Ответить
                                        • > это можно сделать аннотациями?
                                          Если честно - а хрен бы знал. Сейчас покопался в доках - получается, что annotation processor'ы сами по себе не были предназначены для модификации кода, а должны генерить что-то новое - конфиги, новые классы, которые потом будут загружены и.т.п...

                                          Но, как показали некоторые найденные примеры (из-за которых я по глупости и поверил во всесильность процессоров), если перейти на темную сторону заюзав внутреннее API javac'а - com.sun.tools.javac.tree, то можно перепиливать даже код внутри методов.

                                          http://www.docjar.com/docs/api/com/sun/tools/javac/tree/JCTree$JCClassDecl.html
                                          Скорее всего будет достаточно добавить нужный интерфейс в список implementing. Но я совершенно в этом не уверен ;(
                                          Ответить
                                          • Я тоже полез в недра Mirror API и не нашёл простого способа. У Eclipse JDT вроде свой, более богатый compiler api, но так не интересно. Получается, в канонической жабе вроде как нельзя.
                                            Ответить
                                            • > Получается, в канонической жабе вроде как нельзя.
                                              Хотел на OpenJDK потестить чорную магию с API javac'а, и обломался т.к. там нет нужных интерфейсов...
                                              Ответить
                                          • > > это можно сделать аннотациями?
                                            можно модифицировать байт-код и сделать новый класс, и загрузить его новым класслоадером, тем же asm
                                            Ответить
                                            • > загрузить его новым класслоадером
                                              Зачем? Тут вроде речь шла о compile-time преобразованиях...
                                              Ответить
                                              • а, я думал в рантайме... как это делает тот же тапестри... я игрался с asm и у меня получалось сделать новый производный класс , реализующий нужный интерфейс
                                                Ответить
                                                • Я когда-то городил магию с cglib, чтобы решить спринговые жабопроблемы. Ненужнятина это всё.
                                                  Ответить
                                  • > Что он может, чего не могли бы в принципе сделать аннотации
                                    Кэп: подготавливать сорцы к встрече с создателем конпейлятором. Например, опцианально подключать поддержку библиотек, чтобы не тянуть ворох ненужных зависимостей.

                                    > стоит ли это делать таким образом?
                                    В 98% случаев нет. Толко рантайм и куча модулей, только хардкор.
                                    Ответить
                  • А хрен это по сути трамвайная ручка.
                    Ответить
                • Жаба душит.
                  Ответить
            • на компилятор надейся, а сам не плошай
              Ответить
            • C# при использовании атрибута Conditional удаляет только вызовы, сами методы компилируются в IL и доступны через рефлексию.
              Ответить
    • В питоне, кстати, есть doctest, офигенная штука.
      Ответить

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