2017-10-10 5 views
2

Pourquoi String.to_atom code-t-il l'option de codage de la façon suivante: utf8?String.to_atom code l'option de codage erlang.binary_to_atom sous-jacente à: utf8, pourquoi?

https://github.com/elixir-lang/elixir/blob/d6bb3342b7ea8b921b3d4b69f65064c4158c99d7/lib/elixir/lib/string.ex#L1927 def to_atom(string) do :erlang.binary_to_atom(string, :utf8) end

Les options disponibles codant pour Erlang binary_to_atom sont:

latin1 | unicode | utf8 http://erlang.org/documentation/doc-8.0-rc1/erts-8.0/doc/html/erlang.html#binary_to_atom-2

Répondre

4

TL; DR

Parce que l'univers Erlang est enfin installer sur UTF- 8 partout.

Discussion

latin1 va et est en grande partie un sous-ensemble de l'UTF-8 (sauf quelques caractères), unicode est un ancien alias pour utf8, et qui nous laisse avec une seule option universellement applicable: utf8. Ceci est important puisque les atomes UTF-8 (et les chaînes) sont la voie à suivre dans Erlang et aussi dans Elixir.

Si vous traitez des données anciennes avec des codages non-UTF-8, convertissez-les avant votre appel à binary_to_atom/2.

Cela tombe également en ligne avec les nouveaux string et unicode changements de module dans la bibliothèque standard de Erlang - qui peuvent enfin Settle sur UTF-8 en tant que norme généralement acceptée après des décennies d'incertitude (car encodages sont difficiles et il n'y avait pas beaucoup d'accord à ce sujet quand Erlang a été inventé).

Un mot sur les pratiques de codage

Je travaille au Japon le traitement principalement des données commerciales, dont certaines assez vieux, et certains dans encodages vraiment fou. J'ai tendance à coder principalement à Erlang (je préfère les langues minuscules). Lorsque certaines des fonctions des modules de gestion des chaînes plus anciennes et unicode étaient des chaînes écrites se divisent en deux catégories:

  • Une liste de points de code en ASCII (qui a été étendre implicitement pour englober latin1 un peu de temps parce que, bien, les langues européennes étaient une utilisation courante et CJK était un désordre sauvage à l'époque)
  • Certains cauchemar éveillé des zombies dragonfire et gel (parce qu'il y avait zéro accord sur quoi que ce soit d'autre et un gazillion radicalement incomplet, bancales, techniquement «normes» inexactes)

Les temps ont changé. Maintenant, nous savons que les chaînes vont presque toujours être en UTF-8 et tout ce qui est dans Unixverse est finalement réglé, ce qui a eu l'effet agréable d'avoir (à peu près) tous les autres systèmes significatifs sur ce point (sinon interne) , puis à travers des bibliothèques de détection robustes qui peuvent choisir entre UTF-16 et UTF-8).

Les cas où vous avez réellement faire ont non données UTF-8 alors vous savez que ce soit le cas et doit convertir vos données avant de l'envoyer à une fonction universelle telle que binary_to_atom/2. Je pense que nous devrions passer à côté d'inclure un binary_to_atom/1 et éliminer complètement binary_to_atom/2 - which is what has already happened with list_to_atom/1 à partir de Erlang R20 (yay!).

Alors, comment cela affecte-t-il votre code? Lorsque vous commencez à traiter des codages anciens, la complexité de votre code explose soudainement et doit être contenue tout de suite, de peur qu'elle n'infecte votre base de code entière avec folie. La meilleure façon de le faire est de garder les fous en dehors de votre système d'entreprise et faire des conversions sur les bords. Chaque fois que nous traitons de vieilles données qui viennent dans des codages fous nous savons déjà et sommes prêts pour cela - donc nous nous convertissons explicitement en UTF-8 dès le début, il n'y a plus rien à découvrir plus tard dans le système. .

Vous pourriez penser, "Pourquoi ne détectent-ils pas simplement l'encodage de chaque chaîne?" Hélas, il n'y a pas de moyen approprié pour détecter les codages de chaîne. Ce n'est tout simplement pas possible avec un haut degré de confiance. Il devient rapidement une tâche obsolète dans la majorité des cas, car la grande majorité des données générées aujourd'hui est UTF-8 (ou UTF-16, mais il est très rare de rencontrer cela sur le fil).