Converting thoughts to code…being pragmatic.

When we convert our thoughts and logic to code there are times we rely on the language to take decisions on our behalf. While this can be convenient at times it can also lead to bugs and future maintenance problems. One common area for this is in the use of implicit and loose logical comparisons.

Consider the following:

$obj = new User('myName');
$userId = $obj->getUserId();

if($userId){
//code statements
}else{
//some more code statements
}

This does not tell me anything. If a valid user is not found is it a 0, or a -1 or maybe a null. Also what is a valid user Id?

Actually if we were to go by the above then a valid user ID would be:

1. An integer > 0.
2. An integer = -1
3. Any string other than ‘0’

So you can see that this could get a little confusing for programmers who plan to fix an issue with this portion of the code.

Good programming practice suggest that your intentions should be specific and these intentions should be translated into code. So, the above snippet could have been written like this:


if($userId > 0){
//.....
}

indicating that a valid userId should be greater than 0.

Also it could be written like this:


if(isset($userId) && is_int($userId) && $userId > 0){
//.....
}

Something like clearly translates the programmer’s intent.

How you write depends your judgement but remember you are not coding for your self but for others.

If you use if($x) then the following apply:

In if($x), $x evaluates to a true if:

1. $x = true;
2. $x is any integer > 0 or for that matter less than zero. For example -1
3. $x = “1”
4. $x = “-1”
5. $x = any string other than “0” including “false”

It evaluates to a false if:

1. $x = false;
2. $x = null;
3. $x is undefined
4. $x = “”
5. $x = 0
6. $x = “0”
7. $x = array();
8. var $x, private/protected/public $x; in a class without a value

This reminds me of the “empty()” function as listed in the php manual here: http://us2.php.net/manual/en/function.empty.php

The following things are considered to be empty:
“” (an empty string)
0 (0 as an integer)
“0” (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)

So, it goes without saying if($x) is equivalent to if(empty($x));

Also keep your comparison strict when ever possible. It will reduce the chances of bugs creeping in. Consider the case where I have to compare 2 guids.

$selectedGuid = $obj->getSelectedGuid();
$activeGuid = $obj->getActiveGuid();

Let us assume for a minute that we now have:

$selectedGuid = ‘C2670FBA-EA27-AB31-70AD-95521CD9DBB3’;

But for some reason we have:
$activeGuid = 0;

If we now do:

if($selectedGuid == $activeGuid){
//will execute
}

This clearly was not the intent. Instead to be sure we need to take a few more precautions. This happens because when you compare a string to a number, the string gets converted to a number. The ‘guid’ being an alphanumeric string gets converted to a 0.

You could use strict comparison and this problem would be solved like:

if($selectedGuid === $activeGuid){
//will NOT execute
}

I also notice that programmers shy away from lengthy if conditions. Rightly so, the code looks ugly. In such an instance this is what I do:

Rather than do this:

if(isset($guid) && is_string($guid) && strlen($guid) === 38){
//some code
}

I would do this:

$validGuid =  isset($guid) && is_string($guid) && strlen($guid) === 38;

if($validGuid === true){
//some code
}

So the basic rule I try to follow is to convey my intentions clearly and leave nothing for PHP to decide. I try to have my comparisons strict and specific so that there is no room for error. However one must realize that judgment and context also play a vital part in the decision making.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s