Instr <> IndexOf

Last 3 weeks I am trying to convert my biggest project to API2.
But one thing decided me to stop converting to API2.

That’s changing Instr to IndexOf. The biggest problem here is that Instr returns 1 for the first char, while IndexOf returns 0. I do understand the switch to zero based instead of 1 though. It is logical to do so.

This may seem an easy fix, but in very complex code, it is almost impossible unless you debug everything. In my case, the risk is way too high to break my code.

1 Like

Note: One thing that also kept me from changing to IndexOf, is because it is way slower compared to Instr.
But that is fixed in 2022R3 Beta.

Create a Global Module called InstrNew that takes the same parameters as Instr but uses IndexOf internally and returns +1 then global replace Instr for InstrNew. Either forget about it as it should be optimized out at compile time (not tested), go through it at your leisure later, or don’t change it until you need to.

1 Like

I have been going through all my InStrs and Mids one by one. And yes, I managed to break some code.

I’ve also some date code which needs to be rewritten completely.

@JulianS : doing a global method isn’t a good idea for speed reasons.

Be careful of subtract 1 (-1) to StartPosition too.
And be also careful that if StartPosition is greater than the text you are searching in, you will raise an OutOfBoundsException.
issues #69674
Instr returned 0 (not found) in this case.

Just moving from InStr to IndexOf takes almost twice the time. If he was after speed he wouldn’t be moving to API2 :slight_smile:

I use InStr as a way to know if there is an occurence of my search string; I do not always want to get the position.

I do the same with IndexOf for the same reason. You can also search an array with IndexOf.

The bug has been fixed for the next version. It might be a good idea to actually test the bug fix.

1 Like

This speed issue is fixed in the latest beta.

i wish we get a string0 string1 type & class.

FWW I did test this and the speed is now the same (Instr = IndexOf)

1 Like

I never had any trouble remembering that string functions are 1-based and arrays are 0-based. Another instance of Xojo fixing something that wasn’t broken for the sake of some kind of abstract purity, at the expense of users.

3 Likes

I disagree with you on this. The 0-based consistency makes programming much more straightforward.

Here’s another thread where we derailed a little bit and got into a discussion about 1-vs-0:

2 Likes

Yes true, but changing it, for consistency sake, in API2 can break a lot of code, trust me. It’s ok-ish for simple code, but with complex code it is very troublesome to convert to IndexOf.

Yes, but that’s not a good reason. It’s a good reason not to change InStr, but a bad reason to make IndexOf 1-based. IndexOf is a new function. I can’t say it has no legacy attached to it, but there is very little.

I went through all this. Took me about a weekend to convert my project. Yes, InStr to IndexOf is an area that needs special attention. But I found my code simpler to read as a result. It’s a good change despite the growing pains.

3 Likes

I agree. It even made sense to me that way, after being accustomed. Changing them to 0-based is like if I had tried another language; both are pains.

Remembering that InStr is 1-based is the easy part. How it works with similar methods is what makes its response tricky. Tim posted my reasoning, so I’m not going to recap. It’s mentally easier to do Haystack.Left(Haystack.IndexOf(Needle)) than Left(Haystack, InStr(Haystack, Needle) - 1). This is a basic example, but with more complexity, the need to counter offsets is very taxing. Even now, I’m doubting wether or not I got the API1 version of the code correct.

i guess new api2 throw an error for everything like methods in c#.
as example left 100 with a 80 char string fail.
it is not just replace and care about 0 or 1 index.
you have to care about it behave too.

Yeah, that’s true. I wish it didn’t fire an exception, but it makes sense.