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.

Advertisements

Java Strings are immutable, dangit!

For the past three days, and probably for the next three weeks, I am cleaning code. This is usually a good thing, since code is like your room:  It collects random bits and pieces that seemed important at the time, but now you look at and go “what does this thingy do? ”  and “Do I really need three of these things?’ Not to mention the fact that clattared code, like a clattered room, is ungainly and makes hard to find what you’re looking for.

Sometimes, though, you find things that you weren’t looking for. Like this fun little example:

String letters;
for (i=65;i<=91;i++)
  letters+=String.valueOf((char)i);

This little doohickey seems fairly straight forward, doesn’t it? It goes through the letters of the alphabet and produces a string of all the letters one after the other. With a total length of 26 characters (208 bytes.) Nice, simple, effiecent code. Right?

Wrong. Java strings are immutable. Once created, they never, ever change. So that means that the concatenation operator “+=” doesn’t just add another character to the existing string – it creates a whole new one. The old string doesn’t go away (At least not right away. It will get caught in the garbage collector eventually) so instead of having one string “letters” you have this:

A<-letters

A AB<-letters

A AB ABC<-letters

A AB ABC ABCD <-letters

And so on. “letters” always points to the last string created, and eventually the rest of the strings will go away. But a quick calculation shows that in the meantime they take up a combines total of 351 chars. About 2.5 Kilobytes of space. Granted, that’s not much nowadays. But imagine you had this in a loop that ran to 10000? Now we’re talking 40MB of memory (instead of 78k) That’s a bit more of a problem. Make your string increment by two characters at a time instead of one, and we’re up to 193MB (instead of roughly 156k) That’s substantial. Even by today’s standards.

What’s surprising is how often I see things like this in actual code. Not just in our project, but also in other open-source projects and code samples on line. Particularly since this is easy to avoid (use a StringBuffer or StringBuilder). It’s one of those little pitfalls of Java that it seems not all that many people are aware of.