¿Por qué el Perl moderno evita UTF-8 por defecto?


557

Me pregunto por qué la mayoría de las soluciones modernas creadas con Perl no habilitan UTF-8 de forma predeterminada.

Entiendo que hay muchos problemas heredados para los scripts centrales de Perl, donde pueden romper cosas. Pero, desde mi punto de vista, en el 21 st siglo, grandes proyectos nuevos (o proyectos con una perspectiva grande) deben hacer su software de prueba de UTF-8 a partir de cero. Aún así no veo que suceda. Por ejemplo, Moose habilita estrictos y advertencias, pero no Unicode . Modern :: Perl también reduce el repetitivo, pero no maneja UTF-8.

¿Por qué? ¿Hay algunas razones para evitar UTF-8 en los proyectos modernos de Perl en el año 2011?


Comentando @tchrist fue demasiado largo, así que lo agrego aquí.

Parece que no me hice claro. Déjame intentar agregar algunas cosas.

Tchrist y yo vemos la situación de manera bastante similar, pero nuestras conclusiones están completamente en extremos opuestos. Estoy de acuerdo, la situación con Unicode es complicada, pero es por eso que nosotros (usuarios y codificadores de Perl) necesitamos alguna capa (o pragma) que haga que el manejo de UTF-8 sea tan fácil como debe ser hoy en día.

Si Cristo señaló muchos aspectos a cubrir, los leeré y pensaré en ellos durante días o incluso semanas. Aún así, este no es mi punto. tchrist intenta demostrar que no hay una sola forma de "habilitar UTF-8". No tengo tanto conocimiento para discutir con eso. Entonces, me quedo con los ejemplos en vivo.

Jugué con Rakudo y UTF-8 estaba allí cuando lo necesitaba . No tuve ningún problema, simplemente funcionó. Tal vez haya alguna limitación en algún lugar más profundo, pero al principio, todo lo que probé funcionó como esperaba.

¿No debería ser ese un objetivo en el Perl 5 moderno también? Lo enfatizo más: no estoy sugiriendo UTF-8 como el conjunto de caracteres predeterminado para el núcleo de Perl, sugiero la posibilidad de activarlo con un chasquido para aquellos que desarrollan nuevos proyectos.

Otro ejemplo, pero con un tono más negativo. Los marcos deberían facilitar el desarrollo. Hace algunos años, probé los frameworks web, pero los descarté porque "habilitar UTF-8" era muy oscuro. No encontré cómo y dónde conectar el soporte de Unicode. Me llevó tanto tiempo que me resultó más fácil seguir el viejo camino. Ahora vi que había una recompensa por tratar el mismo problema con Mason 2: ¿Cómo hacer que Mason2 UTF-8 esté limpio? . Por lo tanto, es un marco bastante nuevo, pero usarlo con UTF-8 necesita un conocimiento profundo de sus componentes internos. Es como un gran cartel rojo: ¡ALTO, no me uses!

Realmente me gusta Perl. Pero lidiar con Unicode es doloroso. Todavía me encuentro corriendo contra las paredes. De alguna manera, tchrist tiene razón y responde mis preguntas: los nuevos proyectos no atraen a UTF-8 porque es demasiado complicado en Perl 5.


15
Lo siento, pero estoy de acuerdo con @tchrist: UTF-8 es extremadamente difícil. No hay un marco o herramienta que simplemente "active un interruptor" y luego lo maneje correctamente. Es algo en lo que debe pensar directamente al diseñar su aplicación, no es algo que cualquier tipo de marco o lenguaje pueda manejar por usted. Si por casualidad rakudo funcionó para usted, no fue lo suficientemente aventurero con sus casos de prueba, ya que tomará varios de los ejemplos en la respuesta de @ tchrist y la carnicería.
Billy ONeal

12
¿Qué esperas exactamente que haga Moose o Modern :: Perl? ¿Convertir mágicamente datos de caracteres codificados aleatoriamente en archivos y bases de datos en datos válidos nuevamente?
jrockway

13
Qué significa eso? Moose no tiene nada que ver con la manipulación de texto. ¿Por qué debería saber acerca de la codificación de caracteres, y mucho menos elegir una predeterminada para usted? (De todos modos, la razón por la cual los pragmas que enumeras no tocan la codificación es porque la convención es para que los pragmas de Perl afecten el comportamiento léxico . Suponiendo que todo el mundo, otros módulos incluidos, es UTF-8 es simplemente lo incorrecto) Esto no es PHP o Ruby aquí.)
jrockway

8
(Además ... ¿"la mayoría de las aplicaciones modernas de Perl" se rompen en UTF-8? Ciertamente nunca he escrito una aplicación, Perl o de otra manera, que no sea Unicode-clean.)
jrockway

11
Nótese bien. tchrist (Tom Christiansen) publicó su [ training.perl.com/OSCON2011/index.html Materiales de Tom Christiansen para OSCON 2011] sobre Unicode. El titulado "Unicode Support Shootout: The Good, The Bad, and the (most) Ugly" habla sobre el soporte Unicode en diferentes lenguajes de programación. Solo Google Go y Perl5 tienen soporte para Unicode completo, solo Google Go integrado (sin mencionar Perl6).
Jakub Narębski

Respuestas:


1146

𝙎𝙞𝙢𝙥𝙡𝙚𝙨𝙩 : 𝟕 𝘿𝙞𝙨𝙘𝙧𝙚𝙩𝙚 𝙍𝙚𝙘𝙤𝙢𝙢𝙚𝙣𝙙𝙖𝙩𝙞𝙤𝙣𝙨

  1. Establezca su PERL_UNICODEenvariable a AS. Esto hace que todos los scripts de Perl se decodifiquen @ARGVcomo cadenas UTF ‑ 8 y establece la codificación de los tres stdin, stdout y stderr en UTF ‑ 8. Ambos son efectos globales, no léxicos.

  2. En la parte superior de su archivo fuente (programa, módulo, biblioteca, dochupetón), afirme de manera destacada que está ejecutando perl versión 5.12 o superior a través de:

    use v5.12;  # minimal for unicode string feature
    use v5.14;  # optimal for unicode string feature
  3. Habilite las advertencias, ya que la declaración anterior solo habilita restricciones y características, no advertencias. También sugiero promover las advertencias Unicode en excepciones, así que use ambas líneas, no solo una de ellas. Nota sin embargo que bajo v5.14, la utf8clase de aviso comprende otros tres subwarnings la que todos se pueden activar por separado: nonchar, surrogate, y non_unicode. Es posible que desee ejercer un mayor control sobre estos.

    use warnings;
    use warnings qw( FATAL utf8 );
  4. Declare que esta unidad fuente está codificada como UTF ‑ 8. Aunque alguna vez este pragma hizo otras cosas, ahora sirve solo a este propósito singular y no a otro:

    use utf8;
  5. Declare que todo lo que abre un identificador de archivo dentro de este ámbito léxico pero no en otro lugar es asumir que esa secuencia está codificada en UTF ‑ 8 a menos que usted indique lo contrario. De esa manera no afecta el código de otro módulo u otro programa.

    use open qw( :encoding(UTF-8) :std );
  6. Habilitar caracteres con nombre a través de \N{CHARNAME}.

    use charnames qw( :full :short );
  7. Si tiene un DATAidentificador, debe establecer explícitamente su codificación. Si desea que esto sea UTF ‑ 8, diga:

    binmode(DATA, ":encoding(UTF-8)");

Por supuesto, no hay fin de otros asuntos con los que eventualmente te encuentres preocupado, pero estos serán suficientes para aproximar el objetivo estatal de "hacer que todo funcione con UTF-8", aunque para un sentido algo debilitado de esos términos.

Otro pragma, aunque no está relacionado con Unicode, es:

      use autodie;

Es muy recomendable

🌴 🐪🐫🐪 🌞 𝕲𝖔 𝕿𝖍𝖔𝖚 𝖆𝖓𝖉 𝕯𝖔 𝕷𝖎𝖐𝖊𝖜𝖎𝖘𝖊 🌞 🐪🐫🐪 🐁


🎁 🐪 𝕭𝖔𝖎𝖑𝖊𝖗⸗𝖕𝖑𝖆𝖙𝖊 𝖋𝖔𝖗 𝖀𝖓𝖎𝖈𝖔𝖉𝖊⸗𝕬𝖜𝖆𝖗𝖊 𝕮𝖔𝖉𝖊 🐪 🎁


Mi propio repetitivo en estos días tiende a verse así:

use 5.014;

use utf8;
use strict;
use autodie;
use warnings; 
use warnings    qw< FATAL  utf8     >;
use open        qw< :std  :utf8     >;
use charnames   qw< :full >;
use feature     qw< unicode_strings >;

use File::Basename      qw< basename >;
use Carp                qw< carp croak confess cluck >;
use Encode              qw< encode decode >;
use Unicode::Normalize  qw< NFD NFC >;

END { close STDOUT }

if (grep /\P{ASCII}/ => @ARGV) { 
   @ARGV = map { decode("UTF-8", $_) } @ARGV;
}

$0 = basename($0);  # shorter messages
$| = 1;

binmode(DATA, ":utf8");

# give a full stack dump on any untrapped exceptions
local $SIG{__DIE__} = sub {
    confess "Uncaught exception: @_" unless $^S;
};

# now promote run-time warnings into stack-dumped
#   exceptions *unless* we're in an try block, in
#   which case just cluck the stack dump instead
local $SIG{__WARN__} = sub {
    if ($^S) { cluck   "Trapped warning: @_" } 
    else     { confess "Deadly warning: @_"  }
};

while (<>)  {
    chomp;
    $_ = NFD($_);
    ...
} continue {
    say NFC($_);
}

__END__

🎅 𝕹 𝖔 𝕸 𝖆 𝖌 𝖎 𝖈 𝕭 𝖚 𝖑 𝖑 𝖊 𝖙 🎅


Diciendo que "Perl debería [de alguna manera! ] habilitar Unicode de forma predeterminada "ni siquiera comienza a pensar en decir lo suficiente como para ser marginalmente útil en algún tipo de caso raro y aislado. Unicode es mucho más que un repertorio de personajes más grande; También es cómo todos esos personajes interactúan de muchas, muchas maneras.

Incluso las medidas mínimas simples que (algunas) personas piensan que quieren están garantizadas para romper miserablemente millones de líneas de código, código que no tiene oportunidad de "actualizarse" a su nueva y elegante modernidad de Brave New World .

Es mucho más complicado de lo que la gente finge. He pensado en esto muchísimo en los últimos años. Me encantaría que me demuestren que estoy equivocado. Pero no creo que lo sea. Unicode es fundamentalmente más complejo que el modelo que le gustaría imponerle, y aquí hay una complejidad que nunca puede barrer debajo de la alfombra. Si lo intentas, romperás tu propio código o el de otra persona. En algún momento, simplemente tiene que desglosar y aprender de qué se trata Unicode. No puedes fingir que es algo que no es.

🐪 hace todo lo posible para que Unicode sea fácil, mucho más que cualquier otra cosa que haya usado. Si crees que esto es malo, intenta algo más por un tiempo. Luego regrese a 🐪: o habrá regresado a un mundo mejor, o de lo contrario traerá el conocimiento de lo mismo para que podamos utilizar su nuevo conocimiento para mejorar make en estas cosas.


💡 𝕴𝖉𝖊𝖆𝖘 𝖋𝖔𝖗 𝖆 𝖀𝖓𝖎𝖈𝖔𝖉𝖊 ⸗ 𝕬𝖜𝖆𝖗𝖊 🐪 𝕷𝖆𝖚𝖓𝖉𝖗𝖞 𝕷𝖎𝖘𝖙 💡


Como mínimo, aquí hay algunas cosas que parecen ser necesarias para que 🐪 "habilite Unicode de forma predeterminada", como lo dice:

  1. Todo el código fuente debe estar en UTF-8 por defecto. Puedes conseguir eso con use utf8o export PERL5OPTS=-Mutf8.

  2. El DATAmango 🐪 debe ser UTF-8. Tendrá que hacer esto por paquete, como en binmode(DATA, ":encoding(UTF-8)").

  3. Los argumentos del programa para los scripts should deben entenderse como UTF-8 por defecto. export PERL_UNICODE=A, o perl -CA, o export PERL5OPTS=-CA.

  4. Los flujos de entrada, salida y error estándar deben ser UTF-8 predeterminados. export PERL_UNICODE=Spara todos ellos, o I, Oy / o Esolo para algunos de ellos. Esto es como perl -CS.

  5. Cualquier otra manija abierta por 🐪 debe considerarse UTF-8 a menos que se declare lo contrario; export PERL_UNICODE=Do con iy opara algunos particulares de estos; export PERL5OPTS=-CDtrabajaría. Eso los hace -CSADa todos.

  6. Cubre ambas bases más todas las transmisiones con las que abres export PERL5OPTS=-Mopen=:utf8,:std. Ver uniquote .

  7. No quiere perderse los errores de codificación UTF-8. Tratar export PERL5OPTS=-Mwarnings=FATAL,utf8. Y asegúrese de que sus flujos de entrada estén siempre en binmoded :encoding(UTF-8), no solo en :utf8.

  8. Points debe entender que los puntos de código entre 128–255 son los puntos de código Unicode correspondientes, no solo los valores binarios sin propiedad. use feature "unicode_strings"o export PERL5OPTS=-Mfeature=unicode_strings. Eso hará uc("\xDF") eq "SS"y "\xE9" =~ /\w/. Un simple export PERL5OPTS=-Mv5.12o mejor también lo conseguirá.

  9. Los caracteres Unicode con nombre no están habilitados de forma predeterminada, por lo tanto, agregue export PERL5OPTS=-Mcharnames=:full,:short,latin,greeko algo por el estilo. Ver uninames y tcgrep .

  10. Casi siempre necesita acceso a las funciones del módulo estándar deUnicode::Normalize varios tipos de descomposiciones. export PERL5OPTS=-MUnicode::Normalize=NFD,NFKD,NFC,NFKD, y luego siempre ejecuta material entrante a través de NFD y material saliente de NFC. Todavía no conozco ninguna capa de E / S para estas, pero vea nfc , nfd , nfkd y nfkc .

  11. Comparaciones de cadenas en 🐪 usando eq, ne, lc, cmp, sort, & c & CC siempre están equivocados. Entonces, en lugar de @a = sort @b, necesitas @a = Unicode::Collate->new->sort(@b). También podría agregar eso a tu export PERL5OPTS=-MUnicode::Collate. Puede almacenar en caché la clave para las comparaciones binarias.

  12. 🐪 a los incorporados les gusta printfy writehacen lo incorrecto con los datos Unicode. Debe usar el Unicode::GCStringmódulo para el primero, y tanto eso como también el Unicode::LineBreakmódulo para el segundo. Ver uwc y unifmt .

  13. Si quieres que cuenten como enteros, entonces tendrás que ejecutar tus \d+capturas a través de la Unicode::UCD::numfunción porque el atoi incorporado (3) de 🐪 no es lo suficientemente inteligente.

  14. Tendrá problemas con el sistema de archivos en ystems sistemas de archivos. Algunos sistemas de archivos aplican silenciosamente una conversión a NFC; otros hacen cumplir silenciosamente una conversión a NFD. Y otros hacen algo más todavía. Algunos incluso ignoran el asunto por completo, lo que lleva a problemas aún mayores. Entonces debe hacer su propio manejo de NFC / NFD para mantenerse cuerdo.

  15. Toda su 🐪 código que implica a-zo A-Z, y tal debe ser cambiado , incluyendo m//, s///y tr///. Debe destacarse como una bandera roja que grita que su código está roto. Pero no está claro cómo debe cambiar. Obtener las propiedades correctas y comprender sus pliegues de casos es más difícil de lo que piensas. Yo uso unichars y uniprops todos los días.

  16. El código que usa \p{Lu}es casi tan incorrecto como el código que usa [A-Za-z]. Necesita usar \p{Upper}en su lugar, y saber el motivo. Sí, \p{Lowercase}y \p{Lower}son diferentes de \p{Ll}y \p{Lowercase_Letter}.

  17. El código que usa [a-zA-Z]es aún peor. Y no puede usar \pLo \p{Letter}; tiene que utilizar \p{Alphabetic}. ¡No todos los alfabéticos son letras, sabes!

  18. Si está buscando variables 🐪 con /[\$\@\%]\w+/, entonces tiene un problema. Debe buscar /[\$\@\%]\p{IDS}\p{IDC}*/, e incluso eso no es pensar en las variables de puntuación o las variables del paquete.

  19. Si está buscando espacios en blanco, debe elegir entre \hy \v, dependiendo. Y nunca debe usar \s, ya que NO SIGNIFICA [\h\v] , contrario a la creencia popular.

  20. Si está utilizando \nun límite de línea, o incluso \r\n, entonces lo está haciendo mal. Tienes que usar \R, que no es lo mismo!

  21. Si no sabe cuándo y si llamar a Unicode :: Stringprep , será mejor que aprenda.

  22. Las comparaciones que no distinguen entre mayúsculas y minúsculas deben verificar si dos cosas son las mismas letras sin importar sus signos diacríticos y demás. La forma más fácil de hacerlo es con el módulo estándar Unicode :: Collate . Unicode::Collate->new(level => 1)->cmp($a, $b). También hay eqmétodos y tal, y probablemente también debería aprender sobre los métodos matchy substr. Estos tienen ventajas distintas sobre los 🐪 integrados.

  23. A veces eso todavía no es suficiente, y necesita el módulo Unicode :: Collate :: Locale en su lugar, como en su Unicode::Collate::Locale->new(locale => "de__phonebook", level => 1)->cmp($a, $b)lugar. Considere que eso Unicode::Collate::->new(level => 1)->eq("d", "ð")es cierto, pero Unicode::Collate::Locale->new(locale=>"is",level => 1)->eq("d", " ð")es falso. Del mismo modo, "ae" y "æ" son eqsi no usa locales, o si usa el inglés, pero son diferentes en el local islandés. ¿Ahora que? Es difícil, te digo. Puedes jugar con ucsort para probar algunas de estas cosas.

  24. Considere cómo hacer coincidir el patrón CVCV (consonante, vocal, consonante, vocal) en la cadena " niño ". Su forma NFD, que más te conviene haber recordado, se convierte en "nin \ x {303} o". ¿Ahora que vas a hacer? Incluso fingiendo que una vocal es [aeiou](lo cual es incorrecto, por cierto), tampoco podrás hacer algo así (?=[aeiou])\X), porque incluso en NFD un punto de código como 'ø' no se descompone . Sin embargo, probará igual a una 'o' usando la comparación UCA que acabo de mostrarle. No puede confiar en NFD, debe confiar en UCA.


💩 𝔸 𝕤 𝕤 𝕦 𝕞 𝕖 𝔹 𝕣 𝕠 𝕜 𝕖 𝕟 𝕟 𝕖 𝕤 𝕤 💩


Y eso no es todo. Hay un millón de suposiciones rotas que la gente hace sobre Unicode. Hasta que entiendan estas cosas, su código 🐪 se romperá.

  1. El código que supone que puede abrir un archivo de texto sin especificar que la codificación está rota.

  2. El código que asume que la codificación predeterminada es algún tipo de codificación de plataforma nativa está roto.

  3. El código que supone que las páginas web en japonés o chino ocupan menos espacio en UTF-16 que en UTF-8 es incorrecto.

  4. El código que supone que Perl usa UTF ‑ 8 internamente es incorrecto.

  5. El código que supone que los errores de codificación siempre generarán una excepción es incorrecto.

  6. El código que supone que los puntos de código Perl están limitados a 0x10_FFFF es incorrecto.

  7. El código que supone que puede establecer $/algo que funcionará con cualquier separador de línea válido es incorrecto.

  8. El código que supone la igualdad de ida y vuelta en el plegado de mayúsculas y minúsculas, como lc(uc($s)) eq $so uc(lc($s)) eq $s, está completamente roto e incorrecto. Tenga en cuenta que uc("σ")y uc("ς") son ambos "Σ", pero lc("Σ")no puede devolver ambos.

  9. El código que asume que cada punto de código en minúscula tiene uno en mayúscula distinto, o viceversa, está roto. Por ejemplo, "ª"es una letra minúscula sin mayúscula; mientras que tanto "ᵃ"y "ᴬ"son cartas, pero son letras minúsculas no; sin embargo, ambos son puntos de código en minúsculas sin las versiones en mayúsculas correspondientes. ¿Lo tengo? Son no \p{Lowercase_Letter} , a pesar de ser a la vez \p{Letter}y \p{Lowercase}.

  10. El código que supone cambiar el caso no cambia la longitud de la cadena está rota.

  11. El código que supone que solo hay dos casos está roto. También hay un título.

  12. El código que supone que solo las letras tienen mayúsculas y minúsculas está roto. Más allá de las letras, resulta que los números, los símbolos e incluso las marcas tienen mayúsculas y minúsculas. De hecho, cambiar el caso puede incluso hacer que algo cambie su categoría general principal, como \p{Mark}convertirse en un \p{Letter}. También puede hacer que cambie de un script a otro.

  13. El código que supone que el caso nunca depende de la configuración regional está roto.

  14. El código que supone que Unicode da un higo sobre las configuraciones regionales POSIX está roto.

  15. El código que supone que puede eliminar los signos diacríticos para obtener las letras ASCII básicas es malo, inmóvil, roto, con daño cerebral, incorrecto y justifica la pena capital.

  16. El código que asume que los \p{Diacritic}signos diacríticos y las marcas \p{Mark}son lo mismo está roto.

  17. Código que asume las \p{GC=Dash_Punctuation}cubiertas tanto como \p{Dash}está roto.

  18. El código que supone que el guión, los guiones y las desventajas son lo mismo entre sí, o que solo hay uno de cada uno, está roto e incorrecto.

  19. El código que supone que cada punto de código ocupa no más de una columna de impresión está roto.

  20. El código que supone que todos los \p{Mark}caracteres ocupan cero columnas de impresión está roto.

  21. El código que supone que los caracteres que se parecen son iguales está roto.

  22. El código que se supone que los caracteres que no no se parecen son no por igual se rompe.

  23. El código que supone que hay un límite en el número de puntos de código en una fila que solo uno \Xpuede coincidir es incorrecto.

  24. Código que asume \X nunca puede comenzar con un \p{Mark}personaje es incorrecto.

  25. Código que asume que \Xnunca puede contener dos\p{Mark} caracteres está mal.

  26. Código que asume que no puede usar "\x{FFFF}" está mal.

  27. El código que asume un punto de código no BMP que requiere dos unidades de código UTF-16 (sustituto) se codificará en dos caracteres UTF-8 separados, uno por unidad de código, es incorrecto. No lo hace: codifica a un solo punto de código.

  28. El código que transcodifica desde UTF ‐ 16 o UTF ‐ 32 con listas de materiales principales en UTF ‐ 8 se rompe si coloca una lista de materiales al comienzo del UTF-8 resultante. Esto es tan estúpido que el ingeniero debería quitarse los párpados.

  29. El código que asume que el CESU-8 es una codificación UTF válida es incorrecto. Del mismo modo, el código que cree que la codificación U + 0000 como "\xC0\x80"está UTF-8 está rota y es incorrecta. Estos chicos también merecen el tratamiento de los párpados.

  30. El código que asume que los caracteres como >siempre apuntan a la derecha y <siempre apuntan a la izquierda están mal, porque de hecho no lo hacen.

  31. Código que asume si primero imprime el carácter Xy luego el carácter Y, que aparecerán como XYincorrectos. A veces no lo hacen.

  32. El código que asume que ASCII es lo suficientemente bueno para escribir inglés correctamente es estúpido, miope, analfabeto, roto, malvado y equivocado. ¡Afuera con sus cabezas! Si eso parece demasiado extremo, podemos comprometernos: en adelante, pueden escribir solo con el dedo gordo del pie. (El resto será grabado con ductos)

  33. El código que supone que todos los \p{Math}puntos de código son caracteres visibles es incorrecto.

  34. El código que se supone \wcontiene solo letras, dígitos y guiones bajos es incorrecto.

  35. El código que supone eso ^y ~son signos de puntuación está mal.

  36. El código que supone que ütiene una diéresis está mal.

  37. El código que cree que las cosas contienen letras en ellas está mal.

  38. El código que cree \p{InLatin}es el mismo que \p{Latin}se rompe atrozmente.

  39. El código que cree que \p{InLatin}casi siempre es útil es casi seguro que está mal

  40. Código que cree que dada $FIRST_LETTERcomo la primera letra en algún alfabeto y $LAST_LETTERcomo la última letra en ese mismo alfabeto, que [${FIRST_LETTER}-${LAST_LETTER}]tiene algún significado casi siempre está completamente rota, equivocada y sin sentido.

  41. El código que cree que el nombre de alguien solo puede contener ciertos caracteres es estúpido, ofensivo e incorrecto.

  42. El código que intenta reducir Unicode a ASCII no es simplemente incorrecto, nunca se debe permitir que su autor vuelva a trabajar en la programación. Período. Ni siquiera estoy seguro de que se les permita ver de nuevo, ya que obviamente no les ha hecho mucho bien hasta ahora.

  43. El código que cree que hay alguna forma de fingir que las codificaciones de archivos de texto no existen está roto y es peligroso. También podría sacar el otro ojo.

  44. El código que convierte caracteres desconocidos en ?está roto, es estúpido, no funciona y es contrario a la recomendación estándar, que dice ¡ NO HACER ESO!RTFM por qué no.

  45. El código que cree que puede adivinar de manera confiable la codificación de un archivo de texto sin marcar es culpable de una mezcla fatal de arrogancia e ingenuidad que solo solucionará un rayo de Zeus.

  46. Código que cree que puede usar 🐪 printfanchuras para rellenar y justificar que los datos Unicode estén rotos y sean incorrectos.

  47. El código que cree una vez que crea con éxito un archivo con un nombre determinado, que cuando ejecuta lso readdiren su directorio adjunto, en realidad encontrará que el archivo con el nombre con el que lo creó está defectuoso, roto e incorrecto. ¡Deja de sorprenderte por esto!

  48. El código que cree que UTF-16 es una codificación de ancho fijo es estúpido, roto e incorrecto. Revocar su licencia de programación.

  49. El código que trata los puntos de código de un plano de manera diferente a los de cualquier otro plano está ipso facto roto e incorrecto. Volver a la escuela.

  50. Código que cree que cosas como /s/isolo pueden coincidir "S"o "s"están rotas y mal. Te sorprenderias.

  51. El código que se usa \PM\pM*para encontrar grupos de grafemas en lugar de usar \Xestá roto y es incorrecto.

  52. Las personas que desean regresar al mundo ASCII deben ser animadas de todo corazón a hacerlo, y en honor a su gloriosa actualización, se les debe proporcionar gratis una máquina de escribir manual pre-eléctrica para todas sus necesidades de ingreso de datos. Los mensajes que se les envíen deben enviarse a través de un telégrafo a 40 caracteres por línea y entregados personalmente por un servicio de mensajería. DETENER.


😱 𝕾 𝖀 𝕸 𝕸 𝕬 𝕽 𝖄 😱


No sé cuánto más puede obtener "Unicode predeterminado en you" de lo que he escrito. Bueno, sí lo hago: deberías estar usando Unicode::CollateyUnicode::LineBreak también. Y probablemente más.

Como se ve, hay demasiadas cosas Unicode que realmente no tiene que preocuparse de que haya alguna vez existe tal cosa como “por defecto a Unicode”.

Lo que va a descubrir, tal como lo hicimos en 🐪 5.8, que es simplemente imposible imponer todas estas cosas en el código que no ha sido diseñado desde el principio para darles cuenta. Tu egoísmo bien intencionado acaba de romper el mundo entero.

E incluso una vez que lo haga, todavía hay problemas críticos que requieren una gran cantidad de pensamiento para hacerlo bien. No hay un interruptor que pueda activar. Nada más que cerebro, y quiero decir cerebro real , será suficiente aquí. Hay muchas cosas que tienes que aprender. Modulo del retiro a la máquina de escribir manual, simplemente no puede esperar escabullirse por ignorancia. Este es el siglo XXI, y no puedes desear que Unicode se vaya por ignorancia voluntaria.

Tienes que aprenderlo. Período. Nunca será tan fácil que "todo simplemente funciona", porque eso garantizará que muchas cosas no funcionen funcionen, lo que invalida la suposición de que alguna vez puede haber una manera de "hacer que todo funcione".

Es posible que pueda obtener algunos valores predeterminados razonables para muy pocas y muy limitadas operaciones, pero no sin pensar en las cosas mucho más de lo que creo que tiene.

Como solo un ejemplo, el ordenamiento canónico causará verdaderos dolores de cabeza. 😭 "\x{F5}" 'õ' , "o\x{303}" 'õ' , "o\x{303}\x{304}" 'ȭ' y "o\x{304}\x{303}" 'ō̃' deberían coincidir con 'õ' , pero ¿cómo vas a hacer eso? Esto es más difícil de lo que parece, pero es algo que debe tener en cuenta. 💣

Si hay algo que sé sobre Perl, es lo que hacen y no hacen sus bits Unicode, y esto lo prometo: "̲ᴛ̲ʜ̲ᴇ̲ʀ̲ᴇ̲ ̲ɪ̲s̲ ̲ɴ̲ᴏ̲ ̲U̲ɴ̲ɪ̲ᴄ̲ᴏ̲ᴅ̲ᴇ̲ ̲ᴍ̲ᴀ̲ɢ̲ɪ̲ᴄ̲ ̲ʙ̲ᴜ̲ʟ̲ʟ̲ᴇ̲ᴛ̲ ̲" 😞

No puede simplemente cambiar algunos valores predeterminados y obtener una navegación fluida. Es cierto que ejecuto 🐪 con PERL_UNICODEset to "SA", pero eso es todo, e incluso eso es principalmente para cosas de línea de comandos. Para un trabajo real, paso por todos los pasos descritos anteriormente, y lo hago muy, ** muy ** cuidadosamente.


😈 ¡ƨdləɥ ƨᴉɥʇ ədoɥ puɐ ʻλɐp əɔᴉu ɐ əʌɐɥ ʻʞɔnl poo⅁ 😈


56
Como Sherm Pendley señaló: "¡Todos!". Si escribo hoy algo nuevo, UTF-8 debería ser la forma más fácil de hacer las cosas. No lo es. Tu repetitivo lo prueba. No todos tienen ese conocimiento para convertir tantos vasos en las posiciones correctas. Lo siento, tuve un día largo y duro, así que mañana comentaré en la entrada principal más ejemplos.
semana

17
Una conclusión debería ser obvia al leer la lista anterior: no doble las mayúsculas y minúsculas. Solo no lo hagas. Siempre. Computacionalmente costoso y con una semántica que depende de manera crucial de lo que sea que el "local" intenta identificar sin éxito.
Tim Bray

72
¿Soy el único que encuentra irónico que esta publicación de tchrist sea tan completamente diferente en FF / Chrome / IE / Opera, en algún momento hasta el punto de ser ilegible?
damageboy

15
Si bien en general me gusta la publicación y voté, una cosa me molesta muchísimo. Hay mucho "código que ... está roto". Si bien no discuto con la declaración, creo que sería bueno mostrar la ruptura. De esta manera, atravesaría (esta parte de la respuesta) desde una diatriba hasta la educación.

36
@xenoterracide No, no usé puntos de código intencionalmente problemáticos; es una trama para que instales la súper impresionante fuente Symbola de George Douros , que cubre Unicode 6.0. De @depesz No hay espacio aquí para explicar por qué cada suposición rota es incorrecta. @leonbloy Mucho y mucho de esto se aplica a Unicode en general, no solo a Perl. Parte de este material puede aparecer en 🐪 Programming Perl 🐪, cuarta edición , que saldrá en octubre. 🎃 Me queda un mes para ✍ trabajar en ello, y Unicode está ᴍᴇɢᴀ allí; regexes también
tchrist

96

Hay dos etapas para procesar texto Unicode. El primero es "cómo puedo ingresarlo y generarlo sin perder información". El segundo es "cómo trato el texto de acuerdo con las convenciones del idioma local".

La publicación de tchrist cubre ambos, pero la segunda parte es de donde proviene el 99% del texto en su publicación. La mayoría de los programas ni siquiera manejan las E / S correctamente, por lo que es importante comprender eso antes de que empiece a preocuparse por la normalización y la clasificación.

Esta publicación tiene como objetivo resolver ese primer problema

Cuando lees datos en Perl, no importa qué codificación tenga. Asigna un poco de memoria y guarda los bytes allí. Si usted diceprint $str , simplemente borra esos bytes a su terminal, que probablemente está configurado para asumir que todo lo que está escrito en él es UTF-8, y su texto aparece.

Maravilloso.

Excepto que no lo es. Si intenta tratar los datos como texto, verá que algo malo está sucediendo. No necesita ir más allá de lengthver que lo que Perl piensa acerca de su cadena y lo que piensa acerca de su cadena no está de acuerdo. Escribe una frase como: perl -E 'while(<>){ chomp; say length }'y escribe文字化け y obtienes 12 ... no es la respuesta correcta, 4.

Eso es porque Perl asume que su cadena no es texto. Tienes que decirle que es texto antes de que te dé la respuesta correcta.

Eso es bastante fácil; el módulo Encode tiene las funciones para hacer eso. El punto de entrada genérico es Encode::decode(ouse Encode qw(decode) , por supuesto). Esa función toma una cadena del mundo exterior (lo que llamaremos "octetos", una forma elegante de decir "bytes de 8 bits"), y la convierte en un texto que Perl comprenderá. El primer argumento es un nombre de codificación de caracteres, como "UTF-8" o "ASCII" o "EUC-JP". El segundo argumento es la cadena. El valor de retorno es el escalar Perl que contiene el texto.

(También existe Encode::decode_utf8, lo que supone UTF-8 para la codificación).

Si reescribimos nuestro one-liner:

perl -MEncode=decode -E 'while(<>){ chomp; say length decode("UTF-8", $_) }'

Escribimos 文字 化 け y obtenemos "4" como resultado. Éxito.

Esa es la solución al 99% de los problemas de Unicode en Perl.

La clave es que cada vez que ingrese texto en su programa, debe decodificarlo. Internet no puede transmitir caracteres. Los archivos no pueden almacenar caracteres. No hay caracteres en su base de datos. Solo hay octetos, y no puedes tratar los octetos como caracteres en Perl. Debe decodificar los octetos codificados en caracteres Perl con el módulo Encode.

La otra mitad del problema es sacar datos de su programa. Eso es fácil de hacer; solo diga use Encode qw(encode), decida en qué codificación estarán sus datos (UTF-8 a terminales que entienden UTF-8, UTF-16 para archivos en Windows, etc.), y luego envíe el resultado en encode($encoding, $data)lugar de simplemente enviarlo $data.

Esta operación convierte los caracteres de Perl, que es en lo que opera su programa, en octetos que pueden ser utilizados por el mundo exterior. Sería mucho más fácil si pudiéramos enviar caracteres a través de Internet o a nuestras terminales, pero no podemos: octetos solamente. Entonces tenemos que convertir caracteres a octetos, de lo contrario los resultados no están definidos.

Para resumir: codifique todas las salidas y decodifique todas las entradas.

Ahora hablaremos sobre tres problemas que hacen que esto sea un poco desafiante. El primero son las bibliotecas. ¿Manejan el texto correctamente? La respuesta es ... lo intentan. Si descarga una página web, LWP le devolverá su resultado como texto. Si llama al método correcto en el resultado, eso es (y eso es decoded_content, no content, que es solo el flujo de octetos que obtuvo del servidor). Los controladores de la base de datos pueden ser escamosos; si usa DBD :: SQLite solo con Perl, funcionará, pero si alguna otra herramienta ha puesto texto almacenado como una codificación distinta de UTF-8 en su base de datos ... bueno ... no se manejará correctamente hasta que escriba el código para manejarlo correctamente.

La salida de datos suele ser más fácil, pero si ve "caracteres anchos en la impresión", entonces sabe que está confundiendo la codificación en alguna parte. Esa advertencia significa "oye, estás tratando de filtrar personajes de Perl al mundo exterior y eso no tiene ningún sentido". Parece que su programa funciona (porque el otro extremo generalmente maneja los caracteres de Perl sin procesar correctamente), pero está muy roto y podría dejar de funcionar en cualquier momento. Solucionarlo con un explícito Encode::encode!

El segundo problema es el código fuente codificado UTF-8. A menos que diga use utf8en la parte superior de cada archivo, Perl no asumirá que su código fuente es UTF-8. Esto significa que cada vez que dices algo así my $var = 'ほげ', estás inyectando basura en tu programa que romperá todo horriblemente. No tiene que "usar utf8", pero si no lo hace, no debe usar ningún carácter que no sea ASCII en su programa.

El tercer problema es cómo Perl maneja el pasado. Hace mucho tiempo, no existía el Unicode, y Perl asumió que todo era texto o binario latino-1. Entonces, cuando los datos ingresan a su programa y comienza a tratarlos como texto, Perl trata cada octeto como un carácter latino-1. Es por eso que, cuando preguntamos por la longitud de "文字 化 け", obtuvimos 12. Perl asumió que estábamos operando en la cadena latina-1 "æååã" (que tiene 12 caracteres, algunos de los cuales no se imprimen).

Esto se llama una "actualización implícita", y es una cosa perfectamente razonable de hacer, pero no es lo que desea si su texto no es latino-1. Es por eso que es crítico decodificar explícitamente la entrada: si no lo hace, Perl lo hará, y podría hacerlo mal.

Las personas se encuentran con problemas donde la mitad de sus datos es una cadena de caracteres adecuada, y algunos aún son binarios. Perl interpretará la parte que sigue siendo binaria como si fuera texto latino-1 y luego la combinará con los datos de caracteres correctos. Esto hará que parezca que manejar tus personajes correctamente rompió tu programa, pero en realidad, simplemente no lo has solucionado lo suficiente.

Aquí hay un ejemplo: tiene un programa que lee un archivo de texto codificado en UTF-8, pega un Unicode PILE OF POOen cada línea y lo imprime. Lo escribes como:

while(<>){
    chomp;
    say "$_ 💩";
}

Y luego ejecuta algunos datos codificados UTF-8, como:

perl poo.pl input-data.txt

Imprime los datos UTF-8 con una caca al final de cada línea. Perfecto, mi programa funciona!

Pero no, solo estás haciendo una concatenación binaria. Estás leyendo octetos del archivo, eliminando a \ncon chomp y luego añadiendo los bytes en la representación UTF-8 del PILE OF POOpersonaje. Cuando revise su programa para decodificar los datos del archivo y codifique la salida, notará que obtiene basura ("ð ©") en lugar de la caca. Esto lo llevará a creer que decodificar el archivo de entrada es algo incorrecto. No es.

El problema es que la caca se está actualizando implícitamente como latin-1. Si desea use utf8hacer el texto literal en lugar de binario, ¡funcionará nuevamente!

(Ese es el problema número uno que veo cuando ayudo a las personas con Unicode. Se separaron bien y eso rompió su programa. Eso es lo triste de los resultados indefinidos: puedes tener un programa que funciona durante mucho tiempo, pero cuando comienzas a repararlo, se rompe. No se preocupe; si agrega declaraciones de codificación / decodificación a su programa y se rompe, solo significa que tiene más trabajo que hacer. La próxima vez, cuando diseñe con Unicode en mente desde el principio, será ¡más fácil!)

Eso es realmente todo lo que necesita saber sobre Perl y Unicode. Si le dice a Perl cuáles son sus datos, tiene el mejor soporte Unicode entre todos los lenguajes de programación populares. Sin embargo, si asume que mágicamente sabrá qué tipo de texto lo está alimentando, entonces va a tirar a la basura sus datos irrevocablemente. El hecho de que su programa funcione hoy en su terminal UTF-8 no significa que funcionará mañana en un archivo codificado UTF-16. ¡Así que hazlo seguro ahora y ahórrate el dolor de cabeza de destrozar los datos de tus usuarios!

La parte fácil de manejar Unicode es codificar la salida y decodificar la entrada. La parte difícil es encontrar todas sus entradas y salidas, y determinar qué codificación es. Pero es por eso que obtienes mucho dinero :)


El principio se explica bien, pero falta el enfoque práctico para E / S. El uso explícito del Encodemódulo es tedioso y propenso a errores, y hace que leer el código sobre E / S sea realmente doloroso. Las capas de E / S proporcionan una solución, ya que codifican y decodifican de forma transparente, cuando es necesario. openy binmodepermite su especificación, y pragma openestablece los valores predeterminados, como tchrist recomienda en su respuesta.
Palec

48

Todos estamos de acuerdo en que es un problema difícil por muchas razones, pero esa es precisamente la razón para intentar facilitarlo a todos.

Hay un módulo reciente en CPAN, utf8 :: all , que intenta "activar Unicode. Todo".

Como se ha señalado, mágicamente no puede hacer que todo el sistema (programas externos, solicitudes web externas, etc.) también use Unicode, pero podemos trabajar juntos para crear herramientas sensibles que faciliten la solución de problemas comunes. Esa es la razón por la que somos programadores.

Si utf8 :: all no hace algo que crees que debería, mejorémoslo para mejorarlo. O hagamos herramientas adicionales que, juntas, puedan satisfacer las diferentes necesidades de las personas lo mejor posible.

``


55
Veo mucho margen de mejora en el utf8::allmódulo citado . Fue escrito antes de la unicode_stringsfunción, que Fɪɴᴀʟʟʏ ᴀɴᴅ ᴀᴛ Lᴏɴɢ Lᴀsᴛ corrige las expresiones regulares para /utenerlas. No estoy convencido de que genere una excepción en los errores de codificación, y eso es algo que realmente debe tener. No se carga en el use charnames ":full"pragma, que aún no se carga automáticamente. No advierte [a-z]y, printfanchos de cadena, usando en \nlugar de \Ry en .lugar de \X, pero tal vez sean más un Perl::Criticproblema. Si fuera yo, agregaría 𝐍𝐅𝐃 dentro y 𝐍𝐅𝐂 fuera.
tchrist

13
@tchrist El rastreador de problemas para utf8 :: all está aquí. github.com/doherty/utf8-all/issues Les encantaría escuchar sus sugerencias.
Schwern

44
@Schwern: ᴇɴᴏᴛᴜɪᴛs, pero siéntase libre de robar y pellizcar las cosas que he escrito aquí. Para ser honesto, sigo sintiendo / aprendiendo lo que se puede hacer frente a lo que se debe hacer y dónde. He aquí un buen ejemplo de la descarga de la clasificación: unichars -gs '/(?=\P{Ll})\p{Lower}|(?=\P{Lu})\p{Upper}/x' | ucsort --upper | cat -n | less -r. Del mismo modo, pequeños pasos de preprocesamiento como ... | ucsort --upper --preprocess='s/(\d+)/sprintf "%#012d", $1/ge'pueden ser realmente buenos también, y no quisiera tomar las decisiones de otros por ellos. Todavía estoy construyendo mi caja de herramientas Unicode .
tchrist

35

Creo que no entiendes a Unicode y su relación con Perl. No importa de qué manera almacene los datos, Unicode, ISO-8859-1 o muchas otras cosas, su programa debe saber cómo interpretar los bytes que obtiene como entrada (decodificación) y cómo representar la información que desea generar (codificación ) Obtenga esa interpretación incorrecta y confunde los datos. No hay una configuración mágica predeterminada dentro de su programa que le dirá a las cosas fuera de su programa cómo actuar.

Crees que es difícil, muy probablemente, porque estás acostumbrado a que todo sea ASCII. Todo lo que debería haber estado pensando simplemente fue ignorado por el lenguaje de programación y todas las cosas con las que tenía que interactuar. Si todo usara nada más que UTF-8 y no tuviera otra opción, entonces UTF-8 sería igual de fácil. Pero no todo usa UTF-8. Por ejemplo, no desea que su manejador de entrada piense que está obteniendo octetos UTF-8 a menos que realmente lo sea, y no desea que sus manejadores de salida sean UTF-8 si la cosa que lee de ellos puede manejar UTF-8 . Perl no tiene forma de saber esas cosas. Por eso eres el programador.

No creo que Unicode en Perl 5 sea demasiado complicado. Creo que da miedo y la gente lo evita. Hay una diferencia Con ese fin, puse Unicode en Learning Perl, sexta edición , y hay muchas cosas de Unicode en la programación efectiva de Perl . Tienes que pasar el tiempo para aprender y comprender Unicode y cómo funciona. De lo contrario, no podrá utilizarlo de manera efectiva.


3
Creo que tienes un punto: da miedo. ¿Deberia ser? Para mí es una bendición Unicode, usarlo en Perl5 no lo es (no supongo que nada sea ASCII, mi lengua materna necesita al menos iso8859-4). Instalé Rakudo y todo lo que probé con UTF-8 (en este sandbox limitado) funcionó de fábrica. ¿Me he perdido algo? Lo recalco nuevamente: es bueno tener un soporte Unicode ajustado, pero la mayoría de las veces no es necesario. Para alejar el miedo del tema, una forma es que todos lean mucho para comprender lo interno. Otro: tenemos pragma especial, por lo que use utf8_everywherehace feliz a la gente. ¿Por qué no el último?
semana

3
Sigo pensando que te estás perdiendo el punto. Que funciono No necesitas entender lo interno. Debe comprender los aspectos externos y cómo desea manejar cadenas que tienen diferentes codificaciones y diferentes representaciones de los mismos caracteres. Lee el consejo de Tom nuevamente. La mayor parte de lo que dice, apuesto a que encontrarás que Rakudo no lo maneja por ti.
brian d foy

1
@wk: Lee la respuesta de Randy nuevamente. Ya te dijo cuáles son las limitaciones.
brian d foy

2
@brian d foy: creo que esas limitaciones están bien, como dice tchrist, no hay una bala mágica para cada aspecto (lo admito: no vi la mayoría de ellas antes de hacer esta pregunta aquí). Por lo tanto, cuando cubrimos muchas cosas básicas con algo como utf8 :: all, no hay necesidad de que todos construyan su propia plantilla enorme solo para que los conceptos básicos sobre el manejo de utf8 funcionen. Con "sin miedo en absoluto" quiero decir: todos pueden comenzar sus proyectos sabiendo que los aspectos básicos están cubiertos. Sí, tienes razón, todavía hay muchos problemas. Pero cuando comenzar es más fácil, tendremos más personas involucradas en resolverlos. En mi humilde opinión
wk

1
@wk - el único "error" con el "utf8: all" o "uni :: perl es solo uno - no están en el NÚCLEO - por lo que todos deben instalarlo desde el CPAN. Y si crees que esto no es un gran problema acuerdo - repensar por favor - sí, es más fácil usar utf8 con un módulo auxiliar. Sin él, el CORE perl todavía tiene soporte Unicode - pero mucho, mucho complicado. Y esto está mal.
jm666

28

Al leer este hilo, a menudo tengo la impresión de que la gente está usando " UTF-8 " como sinónimo de " Unicode ". Haga una distinción entre los "Puntos de código" de Unicode, que son un pariente ampliado del código ASCII y las diversas "codificaciones" de Unicode. Y hay algunos de ellos, de los cuales UTF-8, UTF-16 y UTF-32 son los actuales y algunos más están obsoletos.

Por favor, UTF-8 (así como todas las demás codificaciones ) existe y solo tiene significado en la entrada o en la salida. Internamente, desde Perl 5.8.1, todas las cadenas se mantienen como "puntos de código" Unicode. Es cierto que debe habilitar algunas funciones que se cubrieron con admiración anteriormente.


19
Estoy de acuerdo en que la gente a menudo confunde Uɴɪᴄᴏᴅᴇ con UTF-8⧸16⧸32, pero es fundamental y críticamente cierto que Uɴɪᴄᴏᴅᴇ es solo un conjunto de caracteres ampliado en relación con ᴀsᴄɪɪ. A lo sumo, eso no es más que un mero ɪsᴏ ‑ 10646 . Uɴɪᴄᴏᴅᴇ incluye mucho más : reglas de cotejo, plegado de mayúsculas y minúsculas, formas de normalización, grupos de grafemas, división de palabras y líneas, guiones, equivum numéricos, anchos, bidireccionalidad, variantes de glifos, comportamiento contextual, configuraciones regionales, expresiones regulares, clases combinadas, cientos de propiedades, & mucho más‼
tchrist

15
@tchrist: el primer paso es llevar los datos a su programa y al mundo exterior sin tirarlos a la basura. entonces puede preocuparse por la clasificación, el plegado de mayúsculas y minúsculas, las variantes de glifos, etc.
jrockway 01 de

77
Estoy de acuerdo, conseguir que Perl no deseche la entrada o la salida debe ser la primera prioridad. Lo que me gustaría era tener un módulo o pragma que pudiera encarnar la siguiente conversación ficticia: "- Estimado Perl. Para este programa, todas las entradas y salidas serán exclusivamente UTF-8. ¿Podrían por favor no desechar mis datos? - Entonces solo UFT-8 que dices. ¿Estás seguro? - Sí. - ¿Realmente, realmente seguro? - Absolutamente. - ¿Y aceptas que podría comportarme de manera extraña si recibo datos que no son UTF-8? - Sí, está bien. - OK entonces."
hlovdal

10

Hay una cantidad realmente horrible de código antiguo en la naturaleza, en gran parte en forma de módulos CPAN comunes. Descubrí que tengo que tener bastante cuidado al habilitar Unicode si uso módulos externos que podrían verse afectados, y todavía estoy tratando de identificar y corregir algunas fallas relacionadas con Unicode en varios scripts de Perl que uso regularmente (en particular, iTiVo falla mal en cualquier cosa que no sea ASCII de 7 bits debido a problemas de transcodificación).


Me refería a usar la -Copción para asegurarme de que Perl esté en la misma página que yo en cuanto a Unicode, porque sigo teniendo que decida usar ISO 8859/1 en lugar de Unicode a pesar de que estoy configurando explícitamente $LANGy $LC_ALLcorrectamente. (Esto en realidad puede reflejar errores en las bibliotecas locales de la plataforma). Sea lo que sea, ha sido muy molesto que no pueda usar iTivo en programas con acentos porque los scripts de Perl que hacen el trabajo se caen con errores de conversión.
geekosaur

3
Un solitario -Csin opciones tiene errores y es propenso a errores . Rompes el mundo. Establezca la PERL5OPTvariable en -Cy verá lo que quiero decir. Lo intentamos de vuelta en v5.8, y fue un desastre. Simplemente no puede ni debe decirle a los programas que no lo esperan que ahora están tratando con Unicode, les guste o no. También hay problemas de seguridad. Por lo menos, todo lo que haga print while <>se romperá si se pasan datos binarios. También lo hará todo el código de la base de datos. Esta es una idea terrible.
tchrist

1
Estaba hablando genéricamente, en realidad, no específicamente -Csin opciones. La invocación específica con la que había estado trabajando era -CSDA. Dicho esto, estuve atascado con 5.8.x durante mucho tiempo (hola MacPorts ...), así que tal vez eso fue parte de eso.
Geekosaur

1
Corro con PERL_UNICODE establecido en SA. Usted NO puede configurarlo para que D.
tchrist

@tchrist: Algunos Perl varmint han estado publicando código que muestra el uso de -CSDA y PERL_UNICODE = SDA . Por favor use su influencia en la comunidad. ¡Debe ser detenido!
Ashley

1

Debe habilitar la función de cadenas Unicode, y esta es la predeterminada si usa v5.14;

Realmente no deberías usar identificadores Unicode especialmente. para el código extranjero a través de utf8, ya que no son seguros en perl5, solo cperl lo hizo bien. Ver, por ejemplo, http://perl11.org/blog/unicode-identifiers.html

Con respecto a utf8 para sus manejadores / secuencias de archivos: debe decidir usted mismo la codificación de sus datos externos. Una biblioteca no puede saber eso, y dado que ni siquiera libc admite utf8, los datos adecuados de utf8 son raros. Hay más wtf8, la aberración de windows de utf8 alrededor.

Por cierto: Moose no es realmente "Modern Perl", simplemente secuestraron el nombre. Moose es perfecto Perl posmoderno estilo Larry Wall mezclado con estilo Bjarne Stroustrup todo funciona, con una aberración ecléctica de la sintaxis perl6 adecuada, por ejemplo, el uso de cadenas para nombres de variables, campos horribles y una implementación ingenua muy inmadura que es 10 veces más lenta que una Implementación adecuada. cperl y perl6 son los verdaderos perls modernos, donde la forma sigue a la función, y la implementación se reduce y optimiza.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.