Thursday, March 5, 2009

Null references

In an earlier post, I described my distaste for null references. I thought I should elaborate a little more with an example. So first, in Python, consider the following.
#Example; Null references.

if __name__=="__main__":
ref1=None
ref2=True
ref3=False

print "REF1",ref1==True
print "REF2",ref2==True
print "REF3",ref3==True

Here we have defined three variables; ref1, ref2, and ref3. In this example, ref1 is supposed to represent a null reference. It is defined as None. This means it is pseudo-defined. There is really no way to differentiate between ref1 and ref3 when running this example. They both evaluate to False. From a developer perspective, this doesn't make things very easy. The two variables (ref1 and ref3), are defined differently yet yield the same result. What gives?

Normally this wouldn't make a difference. Certain variables will have different content but will evaluate to True in truth tests. For instance, consider the following.
#Example; Null references.

if __name__=="__main__":
ref1=""
ref2="My String"
ref3=None

if ref1:
print "REF1 TRUE"
else:
print "REF1 FALSE"
if ref2:
print "REF2 TRUE"
else:
print "REF2 FALSE"
if ref3:
print "REF3 TRUE"
else:
print "REF3 FALSE"
Here, we have altered the definitions of ref1, ref2, and ref3. ref1 is now an empty string. ref2 is now a non-empty string. ref3 is a null reference. Running this example will result in the following:
  • ref1 is False because it is empty. But, it is still a string.
  • ref2 is True because it is a non-empty string.
  • ref3 is False because it is a null reference and hence has no way of knowing if it is True.
Finally, this last example shows how this null reference can really cause havoc.
#Example; Null references.

def print_length(str_obj):
print len(str_obj)

if __name__=="__main__":
ref1=""
ref2="My String"
ref3=None

print_length(ref1)
print_length(ref2)
print_length(ref3)
Here we have the exact some reference variables as the last example. We also have a print_length() function that will print the length of the specified string. The last print_length() invocation will fail because it is a null reference. The first invocation on the empty string works because it is still a string object.

If you want something to evaluate to False until it is non-empty, you can still specify a type that will evaluate to false. If not, build your own Null type.