I have been working on some updates to Hyrule lately and I came across a situation where I had one of those "I wish I could do this" moments. ColdFusion (along with php,asp,etc...) is a loosely typed language. This just means that you don't have to declare a data type of a variable in the language. In other languages such as Java (strongly typed) you must assign a variable a data type. I am not going to get into the pros and cons of both because you can do a quick search and find that out for yourself.

So I am working with a component that has a single function, isValid(). From the name you can probably gather that its going to evaluate some data and return a boolean. The component we are going to use as an example here is the MinValidator.cfc. Don't worry to much about the component itself, lets focus on its task. This component accepts a struct that may look something like this. Now what we need to do is evaluate the value and see if passes some condition. I have always been taught that in these cases the condition should pass until you can find a reason for it not to pass. That is why we have created a variable valid and set it true. If we ran the component as it is everything would pass.

You may be eager to run off and start implementing your min behavior but any good artist doesn't start building without some kind of blueprint. Your first thought might be to write something like this. While this would work you have not stopped to think everything through and ask the important question. Why does min have to refer to just numbers? Min could be the minimum number of characters in a string, the minimum date, the minimum number of rows in a query and so on. With that I realized I needed to switch based on data types. In a loosely typed language such as ColdFusion we have no way to check the type. In a perfect world I would love to be able to do this. Based on a data type we can check the condition and the break out of the switch and return execution back to the caller.

Because we can't do that we have to get a little creative here. First off you should know the difference between simple and complex values. Simple values are strings,lists,numbers,dates,booleans,binary,xml. Complex values are arrays,structures,queries and objects. If I left anything out I am sorry, but you get the idea. The reason we need to separate the 2 is because of the dynamic nature of the language. Take the following example. This will satisfy both of the follwoing statements. So in our case we almost need to follow this logic.

  • If variable is simple data type
    • if numeric : if value < min return false;
    • if date : if value before min return false;
    • else : if string : count characters
The reason we return false is because we have no way of saying I am done get me out of here like we do in a switch (break). So with that this is what I came up with.

In the end its a little more work than my fairy tale scenario but it works. Please don't take this as a "I wish CF did this" because as I said earlier its just the nature of a loosely typed language. You could created your own method that figures out what type it is but in the end I didn't want to have to include that component in every validator so I just went with this. In fact I did create a simple component to do this so if you want to see it let me know. Please comment, thoughts suggests, am I missing something? I up for any kind of feedback on a better solution if its out there.