I guess this isn't surprising - but I certainly wasn't expecting it. Check out the following code snippet:
public function renderPanels(string area, any me, any group = "", any helper="") {
var panels = getPanels();
if(isNull(paensl)) return;
for(var i=1; i<=arrayLen(panels); i++) {
if(panels[i].getArea() == arguments.area) {
Notice anything odd? How about that horrible typo on the 3rd line. But what surprised me was that this didn't throw a variable is undefined error. Since the variable didn't exist, it returned true for isNull. Obviously I expect to get nulls from my getPanels() code (a Page object may have panels) but the typo made it always return true.
Again - 100% obvious and expected - but this is the first time I've done this in CF9.
Archived Comments
That is why I code with a lot of whitespace (line breaks and line statements). Makes it much easier to spot the typos.
Honestly how many times did you read over that and see (panels) :)
This is why working with type-safe languages can be nicer sometimes. ;) In Java, for instance, the typo would have been caught at compile time. That said, CFML is way more flexible and easier to work with, especially for GUI code.
Oh I cant tell you the amount of legacy code with copy and pasted misspellings that I created over the years. "Urses", "Affliations", "Lables".
Then be careful with ColdFusion's IsNull, StructKeyExists, CFParam, etc.
The solution to this naming issue in languages like ColdFusion is comprehensive unit testing or even test-driven development.
I'd argue that structkeyexists, cfparam tests would have fleshed out the issue more clearly. For example, if I CFPARAMed url.di instead of id, I'd get an error as soon as I use it.
That truly is strange. One would expect that other than "isDefined", any other "is" function would die if the variable passed to it doesn't exist. But then, 'null' is just weird. It's like having a sealed container which is not only just empty, but has even had the air vacuumed out of it.
IsNull is not a function. It is a ColdFusion language construct that just happens to look like a function to the casual observer.
Yes, you get errors if you make programming mistakes. That's the way it works. But the question is, what strategies do you have for dealing with and even preventing these mistakes? Do you have a strong type system? Do you have static analysis? Do you practice test-driven development? Do you test your code manually after writing it?
The answer is yes... mostly. ;)
Seriously though - I was just trying to point out a small thing here - not start a larger discussion on best practices. What you say is absolutely true of course.
Cool. And I agree - in most dynamic languages, since there is very little of an intrinsic safety mechanism against misspelling variable names, you simply have to be careful.
Lookin at you, "varaibles"
Lookin at you, "arguements"
(Dammit why do I keep adding an E in there!?!)
@Doug - I do the exact same thing. To correct myself, I know always say to myself 'Ar-goo-ments' while typing it. I then leave out the 'e'.
Hmm.. so IsNull() is basically !IsDefined(..), without the quotes. I am having a ParameterExists() flashback here ...
I found this nice blog entry by Ben Nadel: http://www.bennadel.com/blo...
He has written a very thorough (hey, it's Ben, what do you expect! ;)) explanation of how the isNull() function operates in different contexts. Highly recommended.
On a personal note, I find the IsNull() function utterly useless for a language that does not even implement the concept of NULL.
Utterly useless? I completely disagree. Many of the ORM functions can return isNull, and I find using isNull much more convenient then isDefined.
I happen to like IsNull() a lot. Not because it doesn't much of anything different than StructKeyExists()... but mostly because I like the way it looks. This might the most superficial, shallow decision making ever, but hey, what can you do. I just think this:
isNull( request.foo )
... looks nicer, and perhaps is easier to understand than:
!structKeyExists( request, "foo" )
... not to mention must less typing.
When interacting with say java objects (that do have the concept of null) the name IsNull() does feel more intuitive. I agree it is also less code than some of the alternatives.
But that said, in a lot of basic cf code there is not much practical difference between a variable that has not been defined, and one that was set to null, such as with javacast(). So it seems less useful to me in that context.
Granted, I have not delved into ORM much. So perhaps there is a stronger selling point from the ORM viewpoint.