Just because it’s not an error doesn’t mean it’s right

*** This post belongs to https://bigendian.wordpress.com, all rights reserved ***

I was working on a PHP script the other day, and the damn bastard just wouldn’t work. I mean, the code was fine, no errors, no problems in compilation or anything like that. It ran perfectly, except that it didn’t do what I wanted. Worse than that: it was inconsistent about it, sometimes it was fine, and sometimes the results just didn’t make sense. It all depended on the input it got.

After much head scratching and dark thoughts about throwing my computer out the window and becoming a Shepperd, I found the problem: in one of the functions that was suppose to cleanse the input had a call to strripos when it really needed a call to strrpos, happens.

The thing is that this really shouldn’t happen, and if it does it shouldn’t take so long to diagnose. What a function does should be immediately and unambiguously clear by looking at its name. when you have strripos and strrpos, strtr and strstr, and stripslashes and stripcslashes, that makes it very hard to understand the code. I consider this readability problem to be one of the most fundamental flaws of PHP as a language. Luckily, this was a fairly simple and easily tested script. But consider having to read through 10,000 lines of code just to figure this out. (Yes, I know, you wouldn’t actually read all the code, you’d debug and trace the problem. But the point still stands that the code is harder to read)

Java, thankfully, does not do this. The naming conventions in Java describe ways to avoid this kind of scenario by outlining method names like “toString” “getVariable” and “isValid” which are self-explanatory. But this does not mean that Java is innocent of sin. Consider this scenario: You have a class MyClass and you need to write two constructors for it. Each constructor gets a JFrame and a String, and based on which ones it gets, it will show different information in the frame.

Now, since these are constructors, you can’t give them different names. And since they both have the same number and types of variables, you can’t distinguish them that way. So what you end up doing is distinguishing between them based on the variable order: One constructor is going to be MyClass (String, JFrame) and the other will be MyClass(JFrame, String). All perfectly legal in Java and aren’t you smart.

But now you face the same problem that I faced earlier in PHP: your method calls are non-descriptive and you can’t, based on the method name and signature, tell which constructor your actually using. Sure, you remember which is which now, but what about in six months when you have to get back to it and you’ve forgotten it all, or worse, someone has to maintain your code?

There are several solutions to avoid this kind of problem. My personal favorite is the one suggested by Joshua Bloch in his book “Effective Java” where he recommends using static factory methods instead of constructors.  Consider the two constructors above: If you made them private and instead added static methods with distinct names static getNewMyClassA and static getNewMyClassB you would eliminate the confusion and make it unambiguously clear as to which method does what. Furthermore, you’d gain much greater control over your Object creation, allowing your class to offer objects out of a pool, for example, rather than creating a new object every time. You also have a polymorphic advantage: a static method can return an object of any subclass of its return type, which can be handy.

Debugging and maintaining code are some of the most challenging tasks that a programmer can face. Sometimes, making the code more readable can be the only thing between you and a life as a walking sheepdog. 🙂

B.E.

Advertisements

Overloading Constructors in PHP

Anyone who’s ever programmed in something like Java has probably written an overloaded constructor or two in their life. The ability to use different constructors for different circumstances is fundamental to both the polymorphism and code-reusability parts of OOP, and are amongst the fundamental tools of the trade.

PHP, having started out as a simple web-interaction language, and having only recently added real support for OOP programming, does not support constructor overloading. Annoyingly, Netbeans 6.5.1 doesn’t kick up any sort of warning if you attempt to overload a variable. The page simply would not render, without any mention of why. To make matters worse: it seems that this is such a fundamental issue in PHP that it doesn’t even get to a point where you can attach a debugger and see where things are breaking. You either know this, or you end up sitting in front of an empty browser window scratching your head.

So how can you “overload” constructors in PHP anyway? by using optional arguments, of course!

consider the following function declaration:

class PHPExample{
    public function __construct(array $inputArray="", $in="")
}

The function is obviously the (one and only) constructor method for its class. Yet any of the foolowing calls will invoke it correctly:

$A = new PHPExample();
$A = new PHPExample(array("A","B","C"));
$A = new PHPExample(,4);
$A = new PHPExample(array("A","B","C"), 4);
etc.

The key to this “psudo-overloading” is the list of arguments a function can take. In PHP, you can designate a default value for an argument. For example:

function add ($i, $j=1){
   $k= $i+$j;
   echo $k;
}

If you called the function add(1,2) you would get the response 3.
However, if you called add(1) the function will use it’s default value, and will respond with 2.

So what happens if the default value is null (ie “”)? Then the argument becomes optional. If the function call specifies the argument, it is used. If the call doesn’t have a value for the argument, the argument’s default value (null) is used, and the argument is thus ignored.

So now we have our “psudo-overloading”: Instead of writing different constructors for each set of arguments, we simply write the different senarios into the single constractor. For example:

public function __construct($in=""){
   if(is_array($in)) {
     $this->myarray=$in;
   }else{
     $this->myarray[]="one";
     $this->myarray[]="two";
     $this->myarray[]="three";
   }
}

There just  are a couple of things to keep in mind when using optional variables:

First, optional arguments must come at the END of the argument list:

public function __construct(array $inputArray, $in="") Good

public function __construct(array $inputArray="", $in) Not Good

Second, you must account for optional arguments that you are not using, if you are using arguments that come later in the argument list:

$A = new PHPExample(,4); The comma tells PHP that the 4 is the second argument in the list.

This is by no means a perfect method, and one must hope that eventually PHP will come out with a version that does support constructor overloading. Until then, this is a workable, if possibly a little messy, workaround.

PHP variable fun

A little thing I learned the other day about PHP which may  be useful and is definitely fun:

In PHP a variable identifier can be a combination of any letter, number, and certain ASCII characters (that's actually not quite true, but that's irrelevent). The way PHP identifies a variable is by having a $ in front of it. $thisISaVariable is a PHP var, where as thisISaVariable is not. Remember that PHP is a weakly-typed language, so you don't need a type decleration. Any of these statements are valid:
$myvar=5;  //creates an int var
$myvar=6.7;  //creates a float var
$myvar = "Thisis";  //creates a string var.

Where this gets interesting is in the fact that PHP does it’s variable substitution on the fly. Consider this:

$myvar= "ThisIs";
$$myvar="Fun";
echo $myvar ${$myvar}

ThisIsFun

In the first line PHP sets $myvar to “ThisIs”. It then gets tot he second line where it finds a $ sign. Everything after the sign is the variable name, which is stored in a different variable called myvar. PHP dereferences $myvar to find “ThisIS” so it sets $ThisIs=Fun. And thus we get the output above.

How is this useful? Because it allows you to input something into a variable without knowing the variable name at compile time. You’d notice that in the example above, although a variable with the name $ThisIs was created by the program, it’s name was never explicitly used. We could have easily had different input put into $myvar and created any number of differently named variables, without having to change the script one bit. Neat.