DataEase 8 Beauty - StingToFromBetween at work.
Everything is easy when you have your own team of developers and can just tell them which functions you want them to make. I happen to have that, so to me everything is easy....not so!
Every time we make a new function we always evaluate if this is a function that will be generally useful rather than "specially useful".
A friend of mine is a chef and some years back I gave him a slow cooker (that I had bought and never used). Then sometime later I was moving house and had a garage sale to get rid of "old junk". I observed that my "precious" slow cooker was up for sale - and not only that - it also had the original packaging and instructions down to the shrink wrap - it was obviously unused.
I asked my friend a little peeved: "So you didn't use it then?" I he is not a person to beat around the bush, he just looked at me and said: "You should never have anything in you kitchen that only do one thing."
And at that moment he put words to something that have always been churning at the back of my head. Usefulness!
A hammer, a knife, a pot, a chopping board are all very useful tools because they have general use. A hammer is basically for hammering in nails, but it also serves as everything from lobster cracker to wife killer. Knives equally covers everything from cutting and chopping to via screwdriver and again wife killer ;-). There is specialist hammers and specialist knives, but if you have to have only one you have a normal hammer and a wonder by wonder what is aptly called a chef's knife... Some years back someone gave me a set of cheese cutting boards (small wooden things made of walnut wood). Needless to say they ended up exactly in that category my friend warned me about. I can cut cheese on my big chopping board or on a plate, but I can't use a small piece of tender wood for much in my kitchen so first they ended in a drawer, and in the end on the fire place when I was suitably drunk and out of fire wood.
What I am trying to get to here is that the same goes for functions in software. If a function is to specialised it will never be used. I bet the function you have used the most in DataEase is amongst these three. If(), Jointext() and Concat().
It is obvious that the new functions in 8 need to be somewhat specialised, but not more than they will be generally used an that again bring us to the functions this blog article is about. StringTo(), StringFrom() and StringBetween().
It has been very obvious that the String functions in DataEase hasn't been complete and that is something which we have spent quite some time on in 8. Chr() is a function that is almost up there with Jointext() and Concat() especially back in the ASCII day but it was not included in DataEase until now... still useful though and you need it to insert "prohibited" characters into strings and also if you want to search for what we use as whildcards (* ? ) etc and last but not least, to insert a CR into a memo field when you build it with the new Memo functions.
You can already tell that CHR() qualifies according to the rules above.
So what about StringTo(), StringFrom() and StringBetween()?
To be honest, it was a need for getting the file name from a full path that kind of set it all in motion i.e. StringFrom().
If you think about it, it is not as straight forward as you think, and we wanted to be able to do it on derivation level rather than having to use OML or DQL so we decided to do StringFrom(). But our study showed that we then had to make StringTo() and StringBetween() to for you to be able to manipulate/chop up an entire string so one very specific need ended up with 3 functions. Does't sound like very good "economy" to me...
The need there and then, but the approach and the result was generic and the formula below should show you how generic:
For a project we needed to decode an IP address into an IP number for a location service. IP numbers is a nightmare, because they are represented by 4 numbers that can be from 1 to 3 digits long.
StringTo(Your IP ,".")*16777216+StringTo(StringBetween(Your IP,".","."),".")*65535+StringFrom(StringBetween(Your IP,".","."),".")*256+StringFrom(Your IP,".")
If they had been represented with all 3 all the time...piece of cake... 001.349.012.001 but it isn't. This would be 1.349.12.1 and it is a string.
So how do you find out if 1.349.12.332 is part of the IP range 1.349.12.0 to 1.349.13.255?
You have to convert it to a number and the formula for that is:
( o1, o2, o3, o4 ) - ( 16777216 * o1 )
+ ( 65536 * o2 )
+ ( 256 * o3 )
So you need to get out the 4 numbers separated by the 3 dots.
So with the new String(To,From,Between) functions we simply do.
o1 is simply the first segment i.e. the string up to the first . = StringTo(IP,".")
o4 is the same from the tail = StringFrom(IP,".")
When we know that there is only two more segments in an IP the rest is easy peasy...
o2 is the first segment of the remainder of the string we already know that StringBetween(IP,".",".") will return the remainder of the string.
so o2 must then be StringTo(StringBetween(Ip,".","."),".").
last but not least, o3 is simpy StringFrom(StringBetween(IP,".","."),".")
I can guarantee you that we didn't have decoding of IP addresses into numbers when we created these function, but it show quite well what general usefulness is all about.