? Please explain. From the documentation: UpperCase returns a copy of the string S, with the same text but with all 7-bit ASCII characters between 'a' and 'z' converted to uppercase. To convert 8-bit international characters, use AnsiUpperCase instead.docwiki.embarcadero.com - System.SysUtils.UpperCase - RAD Studio API Documentation
Rik van Kekem Yes exactly. It only converts a..z, nothing else. Not exactly what I expect from a function called "UpperCase" which takes a Unicode string...
Roald van Doorn Of course not, ! is not an upper case letter. I'm talking about UpperCase('aæ') returning 'Aæ', rather than 'AÆ' which any sane (norwegian) person would expect.
Asbjørn Heid​​ It's clearly documented regardless of the stupidity of the naming convention. But I agree with you about the weirdness of it. Maybe somebody knows why the function uppercase() couldn't be changed to handle unicode characters. What compatibility issues could arise? You could of course create a correct one yourself. Actually the ansiuppercase() naming isn't as weird as it sounds. Originally uppercase() was for 7 bit ASCII only (and it still is). ansiuppercase() was for 8 bit ANSI characters. And that one is later expanded/changed for unicode characters and because for backward compatibility they kept the name. Uppercase was already only for ASCII (7 bit) and not for ANSI (8 bit) so they probably didn't see a need to change that one too (because you shouldn't even have used uppercase if you wanted to upper ANSI anyway).
Rik van Kekem The overloaded global functions have been around much longer than the string type helper, that's all (in fact, weren't they already in D7...?). Personally I like using the 'string method' syntax like you however.
Attila Kovacs Because the compiler/RTL/whatever says it does Unicode, and Unicode have these things defined. Well at least for the vast majority of cases (no pun intended).
Attila Kovacs There is no version of Unicode with just a..z defined.
And in your 7bit ASCII world, how would you handle it when your software really needs to print an Æ or similar in order to comply with national regulations?
I don't understand why you keep with uppercase. You should have never used it. Uppercase was for 7 bit characters (but since 7bit doesn't exist as base type it could take char, 8 bit). But it was never intended for 8 bit char ANSI. It's from before computers needed other characters than a..z. For that ansiuppercase was made. Ansiuppercase was also expanded later to handle unicode. The parameter of uppercase was also string/unicode but as it was also with 8bit char, it was never made to handle it. So forget about uppercase. It's deprecated !!! Use ansiuppercase or String.ToUpper. Do you experience any problems with those? (Other than the kept ansi-name for compatibility)
Rik van Kekem Because we have new programmers who come from a non-Delphi background which find a nicely named UpperCase function that takes a Unicode string. Who in their right mind would not expect this to return an uppercase Unicode string?
And that's why I mentioned String.ToUpper. It's in other modern languages too. Odds are they are more familiar with ToUpper than with the archaic uppercase ;)
? Please explain. From the documentation: UpperCase returns a copy of the string S, with the same text but with all 7-bit ASCII characters between 'a' and 'z' converted to uppercase. To convert 8-bit international characters, use AnsiUpperCase instead. docwiki.embarcadero.com - System.SysUtils.UpperCase - RAD Studio API Documentation
ReplyDeleteRik van Kekem Yes exactly. It only converts a..z, nothing else. Not exactly what I expect from a function called "UpperCase" which takes a Unicode string...
ReplyDeleteWould uppercase of 1 then be ! or be dependent on the keyboard layout that the current user has?
ReplyDeleteRoald van Doorn Of course not, ! is not an upper case letter. I'm talking about UpperCase('aæ') returning 'Aæ', rather than 'AÆ' which any sane (norwegian) person would expect.
ReplyDeleteunfortunately that is how it is designed.
ReplyDeleteto achieve your goal you have to use ansiuppercase. very confusing.
Or String.ToUpper :)
ReplyDeleteThere's an echo in here ......
ReplyDeleteI bet this issue of naming arose in their quest to keep backwards compatibility. 😢
ReplyDeleteOf course it did. I think we all know what happened here. Asbjørn Heid is just bemoaning what we are left with.
ReplyDeleteRik van Kekem To make matters worse, it makes no sense to call a function called AnsiUpperCase to convert a Unicode string to upper case.
ReplyDeleteThey took the easy way out, and we're left with the rotten remains.
Asbjørn Heid​​ It's clearly documented regardless of the stupidity of the naming convention. But I agree with you about the weirdness of it. Maybe somebody knows why the function uppercase() couldn't be changed to handle unicode characters. What compatibility issues could arise? You could of course create a correct one yourself. Actually the ansiuppercase() naming isn't as weird as it sounds. Originally uppercase() was for 7 bit ASCII only (and it still is). ansiuppercase() was for 8 bit ANSI characters. And that one is later expanded/changed for unicode characters and because for backward compatibility they kept the name. Uppercase was already only for ASCII (7 bit) and not for ANSI (8 bit) so they probably didn't see a need to change that one too (because you shouldn't even have used uppercase if you wanted to upper ANSI anyway).
ReplyDeleteRik just explained perfectly the back compat rationale behind the state of affairs.
ReplyDeleteThere's actually no need to call the AnsiXXX functions directly - S := UpperCase(S, loUserLocale); S := LowerCase(S, loUserLocale).
ReplyDeleteYes, but if you're going to change your code anyway adding that parameter, why not directly go for S := S.ToUpper; ?
ReplyDeleteRik van Kekem The overloaded global functions have been around much longer than the string type helper, that's all (in fact, weren't they already in D7...?). Personally I like using the 'string method' syntax like you however.
ReplyDeleteThe String helper .ToUpper is also around a long time (but not as long as the uppercase). Although even that one isn't perfect either. Interesting read: https://sergworks.wordpress.com/2009/11/15/how-to-uppecase-lowercase-strings-in-delphi-2009/
ReplyDeleteAttila Kovacs Because the compiler/RTL/whatever says it does Unicode, and Unicode have these things defined. Well at least for the vast majority of cases (no pun intended).
ReplyDeleteAttila Kovacs At the very least "it does Unicode" must mean it supports a version of Unicode. UpperCase does not support any.
ReplyDeleteThe way you're arguing makes it sound like we should just give up and never expect anything beyond 7bit ASCII to work.
Attila Kovacs There is no version of Unicode with just a..z defined.
ReplyDeleteAnd in your 7bit ASCII world, how would you handle it when your software really needs to print an Æ or similar in order to comply with national regulations?
I don't understand why you keep with uppercase. You should have never used it. Uppercase was for 7 bit characters (but since 7bit doesn't exist as base type it could take char, 8 bit). But it was never intended for 8 bit char ANSI. It's from before computers needed other characters than a..z. For that ansiuppercase was made. Ansiuppercase was also expanded later to handle unicode. The parameter of uppercase was also string/unicode but as it was also with 8bit char, it was never made to handle it. So forget about uppercase. It's deprecated !!! Use ansiuppercase or String.ToUpper. Do you experience any problems with those? (Other than the kept ansi-name for compatibility)
ReplyDeleteRik van Kekem Because we have new programmers who come from a non-Delphi background which find a nicely named UpperCase function that takes a Unicode string. Who in their right mind would not expect this to return an uppercase Unicode string?
ReplyDeleteAnd that's why I mentioned String.ToUpper. It's in other modern languages too. Odds are they are more familiar with ToUpper than with the archaic uppercase ;)
ReplyDelete