Здравствуйте, Odi$$ey, Вы писали:
_FR>> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку,
OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
Ну это только си++-нутые так делают (кстати, а как часто в stl ассерты написаны и по каким случаям) (я больше нигде не видел :о)), потому что по-другому не хотят и не могут. Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.
В чём отличие исключения от ассерта? Для меня — именно то, что ассертом я проверяю собственные ошибки (нарушение инвариантов) или, например, то, что системные\сторонние библиотеки делают именно то, что сказано у них в документации\проверено на личном опыте, то есть ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт. А для тех ситуаций, когда мне надо сказать, что меня используют не так, как я ожидаю, я бросаю исключения "наружу". Мне это кажется правильным. Интересно, как поступают другие?
Кстати, не изменяет ли мне склероз, и не писал ли об этом Майерс и Со? Нет под рукой книги…
P.S. Может, отделим ветку?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
коротко: >ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт.
для меня — менять надо тот код, который использует код со сработавшим ASSERT-ом
Здравствуйте, Odi$$ey, Вы писали:
OE>коротко: >>ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт. OE>для меня — менять надо тот код, который использует код со сработавшим ASSERT-ом
То есть, код начиная от того метода, в котором вызван метод асерта, а не начиная с того, где ассерт объявлен\сработал?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Odi$$ey, Вы писали:
OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
Здравствуйте, _FRED_, Вы писали:
_FR>То есть, код начиная от того метода, в котором вызван метод асерта, а не начиная с того, где ассерт объявлен\сработал?
Здравствуйте, Severn, Вы писали:
S>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
тестируй release, assert он только для разработчика, в debug-е
S>>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги? OE>тестируй release, assert он только для разработчика, в debug-е
Не обязательно release, можно просто для найттестов брать билд в котором ассёрты не показывают окошко, а пишут проблему в лог.
В целом я о том что, Ассерт != окошко.
Здравствуйте, Odi$$ey, Вы писали:
OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)
_FR>Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.
Агресивное vs. защитное (agressive vs. defensive) программирование. В агрессивном вызывающая функция должна заботиться о правильности передаваемых параметров, а вызываемая — вылетать нафиг при первом же неудобном случае
Здравствуйте, _pk_sly, Вы писали:
OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор __>нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)
при передаче в конструктор параметром указателя возврат ошибки выглядит странно.. ассерт там имхо более логичен..
лично я использую assert-ы для проверки деталей, ошибки в которых несовместимы с "жизнью" приложения..
коды ошибок — если хочу анализировать результат выполнения..
исключения — если ошибка может быть несовместима с "жизнью" приложения.. а может и не быть Либо в местах, где в начале происходит что то "ошибковозможное", в середине может случиться какая нибудь проблема, а в конце от этого надо красиво избавиться..
Здравствуйте, _pk_sly, Вы писали:
OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор __>нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)
Здравствуйте, Odi$$ey, Вы писали:
OE>а когда же нужны assert-ы?
примерно в таких ситуациях:
a = b;
assert(a == b);
естественно, что это — упрощённая модель, случаи бывают гораздо более витиеватые, разбросанные по функциям, классам и компонентам.
более того, всегда надо помнить что assert — это макрос, который в релизе превращается в ничто!
он обязан не выполнять никакой полезной работы и ошибки через него отлавливаются только в debug-компиляции. если дополнительно требуется проверка условия, она должна быть сделана отдельно. например так:
a = b;
assert(a == b);
if (a != b) { return error; }
это добавляет стабильности релизному коду, одновременно помогая поймать ошибки в дебаге.
Здравствуйте, Odi$$ey, Вы писали:
OE>тестируй release, assert он только для разработчика, в debug-е
А смысл тогда в таких ассертах, если они в тестах будут отключены? Если мой код использует библиотеку криво, я _всегда_ должен получать ошибку — и в дебаге и релизе.
Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация. Если это — классическая модальная мессага которая может вывалиться где-нибудь на веб сервере, то тогда втопку. Можно, как Left2
Здравствуйте, Severn, Вы писали:
OE>>тестируй release, assert он только для разработчика, в debug-е S>А смысл тогда в таких ассертах, если они в тестах будут отключены? Если мой код использует библиотеку криво, я _всегда_ должен получать ошибку — и в дебаге и релизе.
смысл assert-a — "визуализация" и контроль в процессе разработки неких условий, на которые полагается код. Если у тебя функция принимает int ты же не пытаешься тестировать ее заталкивая ей DateTime, string и дальше по списку. Точно также, если на входе функции стоит assert(i != 0) _бессмысленно_ "тестировать" ее передавая ей 0, получать кучу модальных окон и переживать по этому поводу. Срабатываний assert-ов вообще не должно быть, в отличии от результатов проверок входных параметров и еще чего-бы то ни было в runtime.
Обнаружение неправильных параметров в процессе работы — нормальная ситуация, обнаружили — ура, тест прошел, программа работает. Если сработал assert — все, можно сливать воду, программа уже принципиально работает неправильно.
S>Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация.
_FR>> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку, OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
Всё-таки, в большинстве случаев Assert в коде библиотеки должен означать ошибку именно _внутри_ библиотеки (нарушение инвариантов, постусловий и т.п.), которую придётся исправлять её автору
Что же касается расстановки Assert-ов для контроля входных параметров — это разумно делать только для внутрибиблиотечных вызовов, чтобы зафиксировать ситуацию "автор библиотеки — М." (а не "пользователь — М.")
На внешние же вызовы Assert-ы на входе ставить не стоит, хотя бы из соображений unit-тестирования debug-версии.
Здравствуйте, Odi$$ey, Вы писали:
OE>смысл assert-a — "визуализация" и контроль в процессе разработки неких условий, на которые полагается код. Если у тебя функция принимает int ты же не пытаешься тестировать ее заталкивая ей DateTime, string и дальше по списку.
Это уже работа для компилятора, а не для ассерта...
S>>Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация.
OE>это совершенно вторичный вопрос
Эмм...этот вопрос может привести к полному отказу от ассертов — когда они реализованы криво.
Если в коде стоит ASSERT(...), то библиотека должна упасть при неправильном испльзовании. И максимально четко объяснить почему она упала.
Ок, замечательно. Два НО:
1. Но это должно работать и в релизе и в дебаге. Если из-за невнимательного разработчика/тестера/ПМа или еще хз кого, баг просочится на продакшен, то пусть лучше прога со свистом упадет, чем криво посчитает дебеты/кредиты.
2. Но только не вываливать UI элементы в месте вызова ASSERT. Два контрпримера — проблемы с юнит тестированием, проблемы с удаленным запуском на всякого рода серверах.
по поводу #2, скажем, в .нетовской реализации ассерта, можно убрать месседж бокс и включить логирование. Но это не приведет к падению программы. имхо лехче просто кинуть специальный экспешен.
public class Assert
{
public static void That(bool condition)
{
if (!condition) throw new AssertException();
}
Здравствуйте, Severn, Вы писали:
OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
S>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
Если для определенного кода есть юнит тест то, это значит, что данное использование было задумано (если конечно, отбросить ситуации, когда тесты пишутся в беспамятстве). следовательно, для задуманного поведения ассертов быть не должно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, Severn, Вы писали:
S>>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
TK>Если для определенного кода есть юнит тест то, это значит, что данное использование было задумано (если конечно, отбросить ситуации, когда тесты пишутся в беспамятстве). следовательно, для задуманного поведения ассертов быть не должно.
Может я чего не понял. Но хочу я скажем протестировать мой Метод:
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.
Грубо говоря, что было бы, если бы .нетовские классы вместо эксепшена кидали ассерт? Думаю, пациентов с расстроенной психикой определенно прибавилось.