views:

86

answers:

3

I do some checking of arguments in my classes in php using exception-throwing functions. I have functions that do a basic check ( ===, in_array etc ) and throw an exception on false. So I can do assertNumeric($argument, "\$argument is not numeric."); instead of

if ( ! is_numeric($argument) ) {
    throw new Exception("\$argument is not numeric.");
}

Saves some typing

I was reading in the comments of the php manual page on assert() that

As noted on Wikipedia - "assertions are primarily a development tool, they are often disabled when a program is released to the public." and "Assertions should be used to document logically impossible situations and discover programming errors— if the 'impossible' occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is usually unwise: assertions do not allow for graceful recovery from errors, and an assertion failure will often halt the program's execution abruptly. Assertions also do not display a user-friendly error message."

This means that the advice given by "gk at proliberty dot com" to force assertions to be enabled, even when they have been disabled manually, goes against best practices of only using them as a development tool

So, am I 'doing it wrong'? What other/better ways of doing this are there?

A: 

You might consider using typed parameters, and letting the compiler do the type checking for you.

function foo(string $name, integer $number) 
{
  print strlen($name); // Guaranteed to be a string at this point
  print $number / 2;  // Guaranteed to be an int at this point
}
Harold1983-
As this is PHP, there isn't a native string or integer class.
Jordan S. Jones
This type of typed parameters only works for classes and arrays. Strings and integers are not supported.
Chacha102
Jordan is right: you can only use typed parameters for arrays and objects, not strings, ints, floats, etc.
nickf
+1  A: 

Personally I'd second Wikipedia content and not use assertions for regular type checking.

Instead, I'd use PHP Type-Hinting (currently working on objects as php 5.1 and arrays as of php 5.2 ...won't help you with basic data types, but it's still better than nothing); you can then use the functions you were hinting at or even go a little further and consider Ilia Alshanetsky's patch for general type hinting. See here.

maraspin
I don't know. I mean, type hinting arrays and objects is fine, but if the class really needs an integer, or a non-empty string, doing assertions is frowned upon? I'm not going to be able to install the type hinting patch. Should I continue to do what I'm doing and just not call it assertions?
Assertions are only meant for debugging and development environments!
hopeseekr
A: 

As with regular assertions, you should be able to turn your custom assertions off via a convenient global constant or variable or class constructor method. They really do not belong (active) in production code, or active by default in any kind of library. For what you are using them to do, it seems like a waste of CPU cycles even if you could turn them off.

In lower level languages, assertions are very useful to catch very strange situations such as bugs created by over-zealous architecture specific compiler optimizations. For instance, you know that in any sane universe, the asserted condition is going to be true. Then your compiler rips apart the fabric of space time and everything changes. So, perhaps they would be useful if you were using something like PHC or Roadsend to compile your app.

I have also seen 'overly secure' code (mostly in C) where the entrance to every single function is guarded by assertions. I really question the wisdom of doing that.

In short, you want your code to fail gracefully or not at all, not just halt, especially if it depends on user input. Assertions only report conditions that evaluate to false, they don't handle errors.

Tim Post