2010-03-13 9 views
5

J'ai une variable d'environnement définie dans Windows comme TEST=abc£ qui utilise la page de codes Windows-1252. Maintenant, quand je lance un programme Perl test.pl cette valeur d'environnement vient correctement.Comment puis-je utiliser correctement les variables d'environnement codées en tant que Windows-1251 en Perl?

Quand j'appelle un autre code Perl - test2.pl de test1.pl soit par system(..) ou Win32::Process, l'environnement vient brouillées.

Est-ce que quelqu'un peut fournir des informations pour expliquer pourquoi cela pourrait être le cas et comment le résoudre? La version de perl que j'utilise est 5.8.

Si je comprends bien, perl utilise en interne utf-8, de sorte que le processus initial - test1.pl reçu ce droit de Windows-1252utf-8. Lorsque nous appelons un autre processus, devrions-nous revenir à la page de code Windows-1252?

+0

Vous obtiendrez des réponses beaucoup plus rapidement si vous fournissez un code minimal qui démontre le problème. Si vous ne faites que le décrire avec des mots, il reste beaucoup à faire à l'imagination et à la confusion. – daxim

+0

Comment, aucune des douzaines de réponses que vous avez reçues aux six questions que vous avez posées était assez bonne pour être acceptée? –

+0

Oui, je l'ai fait maintenant. – Kartlee

Répondre

8

Cela n'a rien à voir avec le codage de chaîne interne de Perl, mais avec le besoin de décoder correctement les données provenant de l'extérieur. Je vais fournir le cas de test. C'est Strawberry Perl 5.10 sur un Windows XP européen occidental.

test1.pl:

use Devel::Peek; 
print Dump $ENV{TEST}; 
use Encode qw(decode); 
my $var = decode 'Windows-1252', $ENV{TEST}; 
print Dump $var; 

system "B:/sperl/perl/bin/perl.exe B:/test2.pl"; 

test2.pl:

use Devel::Peek; 
print Dump $ENV{TEST}; 
use Encode qw(decode); 
my $var = decode 'IBM850', $ENV{TEST}; 
# using Windows-1252 again is wrong here 
print Dump $var; 

exécuter:

> set TEST=abc£ 
> B:\sperl\perl\bin\perl.exe B:\test1.pl 

sortie (raccourci):

SV = PVMG(0x982314) at 0x989a24 
    FLAGS = (SMG, RMG, POK, pPOK) 
    PV = 0x98de0c "abc\243"\0 
SV = PV(0x3d6a64) at 0x989b04 
    FLAGS = (PADMY, POK, pPOK, UTF8) 
    PV = 0x9b5be4 "abc\302\243"\0 [UTF8 "abc\x{a3}"] 
SV = PVMG(0x982314) at 0x989a24 
    FLAGS = (SMG, RMG, POK, pPOK) 
    PV = 0x98de0c "abc\243"\0 
SV = PV(0x3d6a4c) at 0x989b04 
    FLAGS = (PADMY, POK, pPOK, UTF8) 
    PV = 0x9b587c "abc\302\243"\0 [UTF8 "abc\x{a3}"] 

Vous êtes mordu par le fait que Windows utilise un codage différent pour l'environnement de texte (IBM850) que pour l'environnement graphique (Windows-1252). Un expert doit expliquer les détails plus profonds de ce phénomène.

Edit:

Il est possible de heuristically (ce qui signifie qu'il ne parviendra pas à faire la bonne chose parfois, en particulier pour les chaînes courtes) déterminer encodages. La meilleure solution à usage général est Encode::Detect/Encode::Detect::Detector qui est basée sur Mozilla nsUniversalDetector.

Il existe des moyens de décoder implicitement des données externes telles que open pragma/IO layers et -C switch, mais ils ne traitent que des flux de fichiers et des arguments de programme. À partir de maintenant, de l'environnement doit être décodé explicitement. J'aime mieux quand même, explicite montre le programmeur de maintenance que vous avez pensé le topic à travers.

+0

Merci daxim pour votre réponse. Quelques questions - 1) Est-il possible de déterminer quel codage est utilisé pour les chaînes provenant du monde extérieur? Cela aiderait à décoder en conséquence en Perl. 2) Existe-t-il un moyen d'ordonner à perl de gérer la partie de décodage en interne plutôt que de déterminer elle-même l'encodage utilisé dans le monde externe? -Kartlee – Kartlee

+0

Merci pour le rappel. J'ai fait maintenant pour ce que je pense est acceptable. – Kartlee

Questions connexes