Reputation: 48919
I've discovered the "Design by contract" pattern and how to implement in in PHP. I can't find a real world example of how to do this in PHP. First question is am i'm doing it in the right way? Second one is why the assert callback is not honored?
A static class Asserts
for reusable assertions:
class Asserts
{
public static function absentOrNotNumeric($value)
{
return !isset($value) ? true : is_numeric($value);
}
}
Usage:
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_BAIL, true);
assert_options(ASSERT_WARNING, true);
assert_options(ASSERT_CALLBACK, array('UseAsserts', 'onAssertFailure'));
class UseAsserts
{
private $value;
public function __construct($value)
{
// Single quotes are needed otherwise you'll get a
// Parse error: syntax error, unexpected T_STRING
assert('Asserts::absentOrNotNumeric($value)');
$this->value = $value;
}
public static function onAssertFailure($file, $line, $message)
{
throw new Exception($message);
}
}
// This will trigger a warning and stops execution, but Exception is not thrown
$fail = new UseAsserts('Should fail.');
Only the (right) warning is triggered:
Warning: assert() [function.assert]: Assertion "Asserts::absetOrNotNumeric($value)" failed.
Upvotes: 5
Views: 327
Reputation: 3550
Your exception is being thrown, altering it to:
public static function onAssertFailure($file, $line, $message)
{
echo "<hr>Assertion Failed:
File '$file'<br />
Line '$line'<br />
Code '$code'<br /><hr />";
}
results in a display of the text, some testing discovers that if you alter this option
assert_options(ASSERT_BAIL, false);
The exception will be thrown, so it seems that it bails on the execution prior to throwing the exception.
Hope that helps
Upvotes: 4
Reputation: 146310
Your code: http://codepad.org/y10BlV8m
My code: http://codepad.org/slSX3HKd
Try using double quotes: assert("Asserts::absentOrNotNumeric($value)");
Upvotes: -1