Информация об изменениях

Сообщение Re[16]: Совсем отстой? от 11.11.2016 15:10

Изменено 11.11.2016 15:13 ·

Здравствуйте, Sinix, Вы писали:

S>1. Таки спасибо, интересный спор получился У меня появляется настойчивое подозрение: главная причина спора в том, что ты понимаешь под ассертами что-то большее, чем просто "проверка в коде". Т.е. спор в итоге чисто про терминологию.

Да, про терминологию. Поэтому надо бы отделить мух от котлет. Есть классические ассерты, которые в Плюсах и в прочем майкрософте — которые рисуют диалог с abort/retry, которые нифига толком залоггировать невозможно, которые из релизной сборки вырезаются и т.п. А есть некие нестандартные, самодельные, которые могут и не обладать всеми этими недостатками (а могут обладать другими ). Так что да, проблема не в слове "ассерт", а в наиболее распространённых реализациях.

S>·>Так ассерт не может в принципе "гарантировать, что ни одно из них не передаёт, скажем, 42". Он будет лишь что-то (не)делать, если 42 таки передалось.

S>Может-может. Достаточно покрыть тестами основные сценарии использования и можно с относительной уверенностью говорить, что критичной для нашего кода ошибки нет. Даже если ошибка и вылезет, скажем, у одного из клиентов, то оставленный в коде ассерт сразу её отловит и сообщит куданадо (с помошью клиента или автоматом — это уже детали реализации). В ближайшем патче ошибку исправят.
S>Сам понимаешь, при таком раскладе шанс поймать ошибку на порядки (серьёзно на порядки) выше, чем когда возможность ошибки проверяется в одном тесте из тысячи.
S>Как дополнительный бонус — у нас значительно вырастает полезность тестов, особенно интеграционных. Они проверяют не только входы-выходы, но и корректность кода в целом.
Это же можно достичь и без ассертов, а, скажем, логированием. Ассерты не являются незаменимыми в данном случае.

S>>>А зачем окошко-то? Ассерты здорового человека просто бросают исключение + дают возможность залогировать сработавшие ассерты.

S>·>А теперь, дети, посмотрите на ассерты майкрософта.
S>Угу, это тяжёлые наркотики, не надо на них смотреть. Я ж говорю — проблема в том, что каждый норовит под ассертом понимать что-то сверх "опционально отключаемая проверка в коде".
Но так это именно то что чаще всего используется, особенно новичками, ведь майкрософт ничего плохого не посоветует же...

S>·>Ну обычно ERROR уровень таки не оставляют незамеченным.

S>Юнит-тестами? Да легко. Кто в них лог проверяет?
А в юнит-тестах ассерты мало помогают. Мы ж white-box тестируем, остальное мочим, и явно видим что может случиться что не может.

S>>>·>Мда, похоже, тут спор частично терминологический. Под ассертами понимаются обычно такие проверки, которые отрубаются в проде. А если это такие проверки, которые работают всегда и везде, кидая исключение, то они ничем неотличимы от обычных проверок типа if(x) throw Exception, кроме, может быть, синтаксиса.

S>>>А, это из плюсов, наверно, в наследство досталось. Глянь тут
S>·>Так там я это и прочёл:
S>А вот не надо выборочно цитировать Выделил:
S>

When a program is deployed to production, assertions are typically turned off to avoid any overhead or side effects they may have…

S>Если выделенное не является проблемой для софта — смысл отключать ассерты?
Насчёт оверхеда — согласен, есть такое. Но таких случаев не должно быть сильно много в типичном приложении. С ними можно разобраться персонально.
side effects — ассерты не должны создавть side effects, иначе это тупо баг в коде. Кстати, тоже камень в огород ассертам — они таки могут создавать side effects, а это никак не заэнфорсить, т.е. ещё один источник хитрых багов.

S>>>или тут. Везде основное свойство ассертов — "проверяет ожидания программиста", а не "не работает в релизе".

S>·>А ты сам-то читал?
S>О, снова неполная цитата. Там же дальше написано:
S>

S>Normally, you don't want users to see assertion messages
S>...
S>For highly robust code, assert and then handle the error anyway.

S>Что считать robust code — это уже вопрос предпочтений, про сообщать пользователю — это чисто вопрос реализации, насильно спамить никто не заставляет.
Сообщать пользователю — конечно нельзя, только в виде краш-репорта, который он может тупо переслать службе поддержки, в лучшем случае.

S>Мы предпочитаем отслеживать ошибки даже в продакшне, а не пропускать их молча, но это от реальных требований зависит.

Ну! Это значит, что ассерт это, может быть, и хорошо, программисту может быть так нравится... но "handle the error" всё равно должен быть. Т.е. на ассерты надейся, да сам не плошай. Т.е. такой код:
assert x != 42;
use(x).asNothingHappened();

плохой. В robust code (а собственно зачем вообще писать не robust code?) должно быть:
assert x != 42;
if(x == 42) destroyTheEarth();
use(x).asNothingHappened();

Но тогда остаётся резонный вопрос — _нужны_ ли ассерты вообще в таком коде? Ответ: нет, не нужны, это личное предпочтение программиста, дело привычки, вкусовщина.

S>>>Не дешевле было просто ассерт поставить?

S>·>Лучше в DoWork вставить if(!inited) throw Exception.
S>Блин, мы по кругу ходим. Я ж уже спрашивал: чем ассерты от исключений отличаются? Кроме того, что их можно переиспользовать без копипасты и выборочно исключать в критичных для производительности местах?
Ну да, вопрос в терминах. if-throw я не видел чтобы называли ассертами.

S>·>У тебя публичный контракт с тремя методами Init/DoWork/Clear — а соответственно любой пользователь класса может не следовать этому контракту, значит его надо явно проверять. То что у тебя на данный момент в коде нет таких пользователей это тебе не даёт право надеяться на авось — такой плохой пользователь может получиться позже — из-за неудачного рефакторинга или добавления новой функиональности, а в твоём случае такой пользователь был, но был неявный, из-за рефлексии в этом сериализаторе, видимо.

S>Ну да, о чём и речь. Тут никак без ассерта/проверки не обойтись, одни тесты никак не помогут.
Тесты помогут проверить, что DoWork правильно валится при неверном состоянии инициализации объекта.
Re[16]: Совсем отстой?
Здравствуйте, Sinix, Вы писали:

S>1. Таки спасибо, интересный спор получился У меня появляется настойчивое подозрение: главная причина спора в том, что ты понимаешь под ассертами что-то большее, чем просто "проверка в коде". Т.е. спор в итоге чисто про терминологию.

Да, про терминологию. Поэтому надо бы отделить мух от котлет. Есть классические ассерты, которые в Плюсах и в прочем майкрософте — которые рисуют диалог с abort/retry, которые нифига толком залоггировать невозможно, которые из релизной сборки вырезаются и т.п. А есть некие нестандартные, самодельные, которые могут и не обладать всеми этими недостатками (а могут обладать другими ). Так что да, проблема не в слове "ассерт", а в наиболее распространённых реализациях.

S>·>Так ассерт не может в принципе "гарантировать, что ни одно из них не передаёт, скажем, 42". Он будет лишь что-то (не)делать, если 42 таки передалось.

S>Может-может. Достаточно покрыть тестами основные сценарии использования и можно с относительной уверенностью говорить, что критичной для нашего кода ошибки нет.
Но вот я не понимаю — почему как покрывать тестами, так "досаточно основные сценарии", а вот ассертами покрываем всё остальное? Почему тестами бы не покрыть то, что ты собрался покрыть ассертами?

S>Даже если ошибка и вылезет, скажем, у одного из клиентов, то оставленный в коде ассерт сразу её отловит и сообщит куданадо (с помошью клиента или автоматом — это уже детали реализации). В ближайшем патче ошибку исправят.

S>Сам понимаешь, при таком раскладе шанс поймать ошибку на порядки (серьёзно на порядки) выше, чем когда возможность ошибки проверяется в одном тесте из тысячи.
S>Как дополнительный бонус — у нас значительно вырастает полезность тестов, особенно интеграционных. Они проверяют не только входы-выходы, но и корректность кода в целом.
Это же можно достичь и без ассертов, а, скажем, логированием. Ассерты не являются незаменимыми в данном случае.

S>>>А зачем окошко-то? Ассерты здорового человека просто бросают исключение + дают возможность залогировать сработавшие ассерты.

S>·>А теперь, дети, посмотрите на ассерты майкрософта.
S>Угу, это тяжёлые наркотики, не надо на них смотреть. Я ж говорю — проблема в том, что каждый норовит под ассертом понимать что-то сверх "опционально отключаемая проверка в коде".
Но так это именно то что чаще всего используется, особенно новичками, ведь майкрософт ничего плохого не посоветует же...

S>·>Ну обычно ERROR уровень таки не оставляют незамеченным.

S>Юнит-тестами? Да легко. Кто в них лог проверяет?
А в юнит-тестах ассерты мало помогают. Мы ж white-box тестируем, остальное мочим, и явно видим что может случиться что не может.

S>>>·>Мда, похоже, тут спор частично терминологический. Под ассертами понимаются обычно такие проверки, которые отрубаются в проде. А если это такие проверки, которые работают всегда и везде, кидая исключение, то они ничем неотличимы от обычных проверок типа if(x) throw Exception, кроме, может быть, синтаксиса.

S>>>А, это из плюсов, наверно, в наследство досталось. Глянь тут
S>·>Так там я это и прочёл:
S>А вот не надо выборочно цитировать Выделил:
S>

When a program is deployed to production, assertions are typically turned off to avoid any overhead or side effects they may have…

S>Если выделенное не является проблемой для софта — смысл отключать ассерты?
Насчёт оверхеда — согласен, есть такое. Но таких случаев не должно быть сильно много в типичном приложении. С ними можно разобраться персонально.
side effects — ассерты не должны создавть side effects, иначе это тупо баг в коде. Кстати, тоже камень в огород ассертам — они таки могут создавать side effects, а это никак не заэнфорсить, т.е. ещё один источник хитрых багов.

S>>>или тут. Везде основное свойство ассертов — "проверяет ожидания программиста", а не "не работает в релизе".

S>·>А ты сам-то читал?
S>О, снова неполная цитата. Там же дальше написано:
S>

S>Normally, you don't want users to see assertion messages
S>...
S>For highly robust code, assert and then handle the error anyway.

S>Что считать robust code — это уже вопрос предпочтений, про сообщать пользователю — это чисто вопрос реализации, насильно спамить никто не заставляет.
Сообщать пользователю — конечно нельзя, только в виде краш-репорта, который он может тупо переслать службе поддержки, в лучшем случае.

S>Мы предпочитаем отслеживать ошибки даже в продакшне, а не пропускать их молча, но это от реальных требований зависит.

Ну! Это значит, что ассерт это, может быть, и хорошо, программисту может быть так нравится... но "handle the error" всё равно должен быть. Т.е. на ассерты надейся, да сам не плошай. Т.е. такой код:
assert x != 42;
use(x).asNothingHappened();

плохой. В robust code (а собственно зачем вообще писать не robust code?) должно быть:
assert x != 42;
if(x == 42) destroyTheEarth();
use(x).asNothingHappened();

Но тогда остаётся резонный вопрос — _нужны_ ли ассерты вообще в таком коде? Ответ: нет, не нужны, это личное предпочтение программиста, дело привычки, вкусовщина.

S>>>Не дешевле было просто ассерт поставить?

S>·>Лучше в DoWork вставить if(!inited) throw Exception.
S>Блин, мы по кругу ходим. Я ж уже спрашивал: чем ассерты от исключений отличаются? Кроме того, что их можно переиспользовать без копипасты и выборочно исключать в критичных для производительности местах?
Ну да, вопрос в терминах. if-throw я не видел чтобы называли ассертами.

S>·>У тебя публичный контракт с тремя методами Init/DoWork/Clear — а соответственно любой пользователь класса может не следовать этому контракту, значит его надо явно проверять. То что у тебя на данный момент в коде нет таких пользователей это тебе не даёт право надеяться на авось — такой плохой пользователь может получиться позже — из-за неудачного рефакторинга или добавления новой функиональности, а в твоём случае такой пользователь был, но был неявный, из-за рефлексии в этом сериализаторе, видимо.

S>Ну да, о чём и речь. Тут никак без ассерта/проверки не обойтись, одни тесты никак не помогут.
Тесты помогут проверить, что DoWork правильно валится при неверном состоянии инициализации объекта.