Сотрудник несколько раз добавил команду assert в наших библиотеках в местах, где я использовал бы оператор if и выбрал исключение. (Я даже не слышал об этом до этого.) Вот пример того, как он это использовал:
assert('isset($this->records); /* Records must be set before this is called. */');
Я бы сделал:
if (!isset($this->records)) { throw new Exception('Records must be set before this is called'); }
Из чтения PHP-документов на assert , похоже, рекомендуется убедиться, что assert активен и добавить обработчик перед использованием assert. Я не могу найти место, где он это сделал.
Итак, мой вопрос заключается в том, что использовать утвердительную идею, учитывая вышеизложенное, и следует ли использовать ее чаще, а не if и exceptions?
Еще одно замечание: мы планируем использовать эти библиотеки для различных проектов и серверов, включая проекты, в которые мы, возможно, даже не входят (библиотеки имеют открытый исходный код). Разве это не влияет на использование assert?
Эмпирическое правило, применимое на большинстве языков (все, что я смутно знаю), заключается в том, что assert
используется для утверждения, что условие всегда истинно, тогда как if
является подходящим, если возможно, что он иногда терпит неудачу.
В этом случае я бы сказал, что assert
является подходящим (основанным на моем слабом понимании ситуации), потому что records
всегда должны быть установлены до того, как будет вызван данный метод. Таким образом, неспособность установить запись будет ошибкой в программе, а не условием выполнения. Здесь assert
помогает обеспечить (при адекватном тестировании), что нет возможного пути выполнения программы, который может привести к тому, что код, который охраняется, будет вызываться без records
.
Преимущество использования assert
в отличие от if
заключается в том, что assert
обычно можно отключить в производственном коде, что уменьшает накладные расходы. Такие ситуации, с которыми лучше всего справляться, if
могут возникнуть во время работы в производственной системе, и поэтому ничего не теряется, поскольку они не могут их отключить.
Это полностью зависит от вашей стратегии развития. Большинство разработчиков не знают assert()
и используют последующие модульные тесты. Но инициативные и встроенные схемы тестирования могут иногда быть полезными.
Утверждение полезно, поскольку оно может быть включено и отключено. Это не снижает производительность, если такой обработчик не определен. У вашего колледжа нет его, и вы должны разработать код, который временно включает его в среду разработки (если E_NOTICE / E_WARNING включены, то должен быть обработчик утверждения). Я иногда использую его, когда мой код не может смешивать смешанные переменные типы – я обычно не занимаюсь строгой типизацией в слабо типизированном PHP, но там случайные варианты использования:
function xyz($a, $b) { assert(is_string($a)); assert(is_array($b));
Который, например, компенсировал бы отсутствие спецификаторов типа string $a, array $b
. PHP5.4 будет поддерживать их, но не проверять.
Подумайте о том, что он утверждает, что «комментарии власти». Вместо комментария вроде:
// Note to developers: the parameter "a" should always be a number!!!
использовать:
assert('is_numeric(a) /* The parameter "a" should always be a number. */');
Значения абсолютно одинаковы и предназначены для одной и той же аудитории, но первый комментарий легко забыт или проигнорирован (независимо от количества восклицательных знаков), в то время как «комментарий силы» не только доступен для людей, чтобы читать и понимать, он также постоянно тестируется машиной во время разработки и не будет проигнорирован, если вы настроите правильную обработку утверждений в коде и в привычках работы.
Таким образом, утверждения являются совершенно иной концепцией, чем если (ошибка) … и исключения, и они могут сосуществовать.
Да, вы должны комментировать свой код, и да, вы должны использовать «комментарии по мощности» (утверждает), когда это возможно.
Assert не является заменой нормального управления потоком, например if
или exceptions, поскольку он предназначен только для отладки во время разработки.
Assert следует использовать только в разработке, поскольку он полезен для отладки. Поэтому, если вы хотите, вы можете использовать их для разработки своего сайта, но вы должны использовать исключения для живого веб-сайта.
Важное примечание относительно утверждения в PHP. В отличие от других языков с конструкцией assert, PHP не полностью отбрасывает утверждения assert – он рассматривает его как функцию (выполняйте debug_backtrace () в функции, вызываемой утверждением). Поворот утверждений, кажется, просто hotwire функция в ничего не делает в двигателе.
Проблема возникает в том, что assert будет принимать любой аргумент, но если аргумент не является строкой, тогда assert получает результаты выражения, включенного или выключенного. Вы можете проверить это с помощью следующего кода.
<?php function foo($a) { echo $a . "\n"; return TRUE; } assert_options(ASSERT_ACTIVE, FALSE); assert( foo('You will see me.')); assert('foo(\'You will not see me.\')'); assert_options(ASSERT_ACTIVE, TRUE); assert( foo('Now you will see')); assert('foo(\'both of us.\')');
Учитывая намерение утверждать, что это ошибка, и давняя, поскольку она была на языке, поскольку утверждение было введено еще в PHP 4.
Строки, переданные в assert, оцениваются со всеми вытекающими из этого последствиями производительности и опасностями, но это единственный способ заставить утверждения assert работать так, как они должны в PHP.
Вы, коллега, действительно пытаетесь применить Design-by-Contract (TM) с языка Эйфеля и на основе книги: Object Oriented Software Construction, 2nd Edition.
Утверждение, которое он использовал, было бы {P} – частью Логики Хоара или Творца Хоара: {P} C {Q}, где {P} является предварительным условием assert (ion) s и {Q} – сообщение -состояние assert (ion) s.
Я хотел бы обратить внимание на советы, связанные с функцией утверждения в PHP с ошибками. Вы не хотите использовать багги-код. То, что вы действительно хотите, – создатели PHP, чтобы исправить ошибку в assert. Пока они этого не сделают, вы можете использовать утверждение, но используйте его, помня о его нынешнем багги.
Более того, если функция assert не работает, я предлагаю вам не использовать ее в производственном коде. Тем не менее, я рекомендую вам использовать его в коде разработки и тестирования, где это необходимо.
Наконец, если вы изучите «Дизайн за контрактом», вы обнаружите, что есть последствия для использования булевых утверждений в свете объектно-ориентированного классического наследования – то есть вы должны никогда не ослабить предварительное условие и не ослабить пост-условие , Это может быть опасно для ваших полиморфных дочерних объектов, взаимодействующих друг с другом. Пока вы не поймете, что это значит, я оставил его в покое!
Более того, я настоятельно рекомендую, чтобы создатели PHP сделали всестороннее исследование «Дизайн за контрактом» и попытались поместить его в PHP как можно скорее! Затем всем нам может быть полезен компилятор / интерпретатор, поддерживающий DbC, который будет обрабатывать проблемы, отмеченные в ответах (см. Выше):
ПРИМЕЧАНИЕ. Даже использование вами заявления if в качестве замены для утверждения (предварительного условия) будет иметь ужасные последствия, если оно используется для усиления предпосылки или ослабления пост-состояния. Чтобы понять, что это значит, вам нужно будет изучить «Дизайн за контрактом», чтобы знать! 🙂
Счастливое обучение и учеба.