David Schwartz 426 Posted September 22, 2020 (edited) I'm using Tokyo 10.2.3 and poking around the string helper functions, and noticed there's a function .Contains( string ) : boolean I want a case-insensitive version. ContainsText(string) doesn't make sense. But then I noticed there's a Lowercase function. But it's Lowercase(string).... These are all class functions so they don't have an object/record attached. So given var aStr : string; it looks like you can't say: if aStr.Lowercase.Contains( 'xyz' ) then ... You need to say: if ContainsText( aStr, 'xyz' ) to get what you want. So what's the point? Looking at the members of this string record helper, it appears that a ton of members are functions that take an argument that should be the string they're "helping". I'm kind of baffled at the apparent lack of utility of: aStr.Lowercase(aStr) when it's the same as Lowercase(aStr). There's a nice variety of functions there, but since they all take an explicit argument, they appear to be gratuitous since the string in front is ignored. What am I missing? Edited September 22, 2020 by David Schwartz Share this post Link to post
David Heffernan 2345 Posted September 22, 2020 (edited) DELETED: because it was nonsense Edited September 22, 2020 by David Heffernan Share this post Link to post
Uwe Raabe 2057 Posted September 22, 2020 I agree about Contains missing a case-insensitive option. On the other hand, the requested LowerCase functionality is already there under the name ToLower. Alas, there are more functions missing from the string helper where you need to fall back to the global ones. Share this post Link to post
Fr0sT.Brutal 900 Posted September 22, 2020 43 minutes ago, Uwe Raabe said: I agree about Contains missing a case-insensitive option. On the other hand, the requested LowerCase functionality is already there under the name ToLower. In general, AFAIK, comparing lowercased versions <> case-insensitive comparing. It's the case for some languages. Moreover, in theory direct case-insensitive comparation should be faster than creating a new string + comparing because many languages do not have case at all. 1 Share this post Link to post
Stefan Glienke 2002 Posted September 22, 2020 (edited) Fun fact: .net framework also is missing this in its String.Contains but .net core added an overload where you can pass an additional option how to compare. Let's remember back when TStringHelper was introduced into Delphi... yep that must have been around the time when .net did not have the overload yet (was introduced in core 2.1) Edited September 22, 2020 by Stefan Glienke 1 Share this post Link to post
Anders Melander 1782 Posted September 22, 2020 2 hours ago, David Schwartz said: What am I missing? The manual apparently 1 hour ago, Fr0sT.Brutal said: In general, AFAIK, comparing lowercased versions <> case-insensitive comparing. There's a string.ToLowerInvariant for that purpose. 1 hour ago, Fr0sT.Brutal said: many languages do not have case at all. The ancient Egyptians? I think they just used a larger chisel for emphasis 48 minutes ago, Stefan Glienke said: Let's remember back when TStringHelper was introduced into Delphi... yep that must have been around the time when .net did not have the overload yet That also makes it easier to write the feature specification: Just copy everything that .NET does. In some cases they even copied their documentation verbatim but failed to realize that it referenced stuff that they hadn't copied. I think a big problems with the string helpers is that they operate on zero based string indices. As if we didn't have enough opportunity off-by-one errors already. 2 Share this post Link to post
Lars Fosdal 1792 Posted September 22, 2020 31 minutes ago, Anders Melander said: The ancient Egyptians? I think they just used a larger chisel for emphasis ROFL! Share this post Link to post
Uwe Raabe 2057 Posted September 22, 2020 48 minutes ago, Anders Melander said: I think a big problems with the string helpers is that they operate on zero based string indices Actually, I like this and make heavy use of it. begin if Value.StartsWith(Prefix, IgnoreCase) then Result := Value.Substring(Prefix.Length) else Result := Value; end; is just easier to read than var isPrefixed: Boolean; begin if IgnoreCase then isPrefixed := StartsText(Prefix, Value) else isPrefixed := StartsStr(Prefix, Value); if isPrefixed then Result := Copy(Value, Length(Prefix) + 1, Length(Value)) else Result := Value; end; 3 Share this post Link to post
Anders Melander 1782 Posted September 22, 2020 2 minutes ago, Uwe Raabe said: just easier to read I'm not saying "don't use string helpers". I'm saying that if they had made them 1-based like God intended then there would have been less confusion. Now we have one set of functions that are 1-based and one that is 0-based. How is that improvement? Ironically I had to look at your 1-based example to figure out what you 0-based example did. Here's a 1-based version without the bias: begin Result := Value; if Result.StartsWith(Prefix, IgnoreCase) then Delete(Result, 1, Prefix.Length); end; 1 1 Share this post Link to post
Rollo62 536 Posted September 22, 2020 7 minutes ago, Anders Melander said: made them 1-based like God intended The 0 took a long way over centuries. Maybe HE was not aware of that when HE created the world in 7 days. Share this post Link to post
Anders Melander 1782 Posted September 22, 2020 I think maybe she used a 3 bit computer and the "7 days" legend is just the result of the actual count overflowing. Anyway. I was referring to an actual entity, not an imaginary one. Share this post Link to post
Fr0sT.Brutal 900 Posted September 22, 2020 2 hours ago, Anders Melander said: The ancient Egyptians? I think they just used a larger chisel for emphasis Contemporary Chinese, Japanese, Arabs, Thais, Koreans, Indians etc are roflin' with you 1 Share this post Link to post
Rollo62 536 Posted September 22, 2020 (edited) 3 hours ago, Anders Melander said: I think maybe she used a 3 bit computer and the "7 days" legend is just the result of the actual count overflowing. Anyway. I was referring to an actual entity, not an imaginary one. Probably like that, with full control over address and data bus (only with 3 bit data bus). Simple operation, one switch at a time, switch 1 = 1, switch 2 = 2, switch 3 = 4 (WHAT ??) While the "0" in those days was considered to be "AI", based on fuzzy quantum states. Until then: This (not further known) person invented the "0", to be used in a computer: From that day the real 3-Bit computer was born, and could made first calculations: switch 1,2,3 OFF = 00 switch 1 = 1 switch 2 = 2 switch 3 = 4 (still nobody knew what was going on here, it should be 3, well who cares) switch 1,2,3 ON = 007 That was the day, HE, SHE or IT was happy, and called it SUM-Day. (Later the romans made wrong translation, we call it now sunday). Edited September 22, 2020 by Rollo62 2 Share this post Link to post
Anders Melander 1782 Posted September 22, 2020 48 minutes ago, Rollo62 said: Simple operation, one switch at a time, switch 1 = 1, switch 2 = 2, switch 3 = 4 (WHAT ??) 1 bit, 2 bit, 3 bit, 4 4 bit, 3 bit, 2 bit, 1 You're bit, he's bit, no bit, none - Eminem 1 Share this post Link to post
David Schwartz 426 Posted September 22, 2020 My question had more to do with the fact that the string helpers all appear to take an argument that's redundant. that is, (aStr.LowerCase = LowerCase(aStr) should be true. Here you apparently need to say: aStr.LowerCase(aStr) which just seems silly. There are a TON of string helper methods that require the parameter you're working with as an explicit argument. Share this post Link to post
Attila Kovacs 629 Posted September 22, 2020 8 minutes ago, David Schwartz said: There are a TON of string helper methods that require the parameter you're working with as an explicit argument. Mind the declaration of those helper routines. The ones needing a parameter are for sure class methods, thus they will as work with aStr.xyz() as with String.xyz(); In this case the ToLower is non-class method, LowerCase is. Now if you wonder why are they called differently, try boolean.ToString(True); and once you found out what is happening try not to scream. Share this post Link to post
Anders Melander 1782 Posted September 23, 2020 11 hours ago, Attila Kovacs said: try boolean.ToString(True); and once you found out what is happening try not to scream Yeah, that one is one of the more stupid things I've encountered. But what does it have to do with the naming? Share this post Link to post