UpperCase not actually returning an upper case string... what a lovely design decision that was!

Comments

  1. ? 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

    ReplyDelete
  2. 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...

    ReplyDelete
  3. Would uppercase of 1 then be ! or be dependent on the keyboard layout that the current user has?

    ReplyDelete
  4. 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.

    ReplyDelete
  5. unfortunately that is how it is designed.
    to achieve your goal you have to use ansiuppercase. very confusing.

    ReplyDelete
  6. I bet this issue of naming arose in their quest to keep backwards compatibility. 😢

    ReplyDelete
  7. Of course it did. I think we all know what happened here. Asbjørn Heid  is just bemoaning what we are left with.

    ReplyDelete
  8. Rik van Kekem To make matters worse, it makes no sense to call a function called AnsiUpperCase to convert a Unicode string to upper case.

    They took the easy way out, and we're left with the rotten remains.

    ReplyDelete
  9. 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).

    ReplyDelete
  10. Rik just explained perfectly the back compat rationale behind the state of affairs.

    ReplyDelete
  11. There's actually no need to call the AnsiXXX functions directly - S := UpperCase(S, loUserLocale); S := LowerCase(S, loUserLocale).

    ReplyDelete
  12. Yes, but if you're going to change your code anyway adding that parameter, why not directly go for S := S.ToUpper; ?

    ReplyDelete
  13. 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.

    ReplyDelete
  14. The 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/

    ReplyDelete
  15. 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).

    ReplyDelete
  16. Attila Kovacs At the very least "it does Unicode" must mean it supports a version of Unicode. UpperCase does not support any.

    The way you're arguing makes it sound like we should just give up and never expect anything beyond 7bit ASCII to work.

    ReplyDelete
  17. 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?

    ReplyDelete
  18. 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)

    ReplyDelete
  19. 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?

    ReplyDelete
  20. 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 ;)

    ReplyDelete

Post a Comment