2010-03-13 10 views
5

Ho una variabile di ambiente impostata in Windows come TEST=abc£ che utilizza la tabella codici Windows-1252. Ora, quando eseguo un programma Perl test.pl, questo valore di ambiente viene visualizzato correttamente.Come posso utilizzare correttamente le variabili di ambiente codificate come Windows-1251 in Perl?

Quando chiamo un altro codice Perl - test2.pl da test1.pl sia da system(..) o Win32::Process, l'ambiente viene confuso.

Qualcuno può fornire informazioni perché questo potrebbe essere e come risolverlo?

La versione di perl che sto utilizzando è 5.8.

Se la mia comprensione è giusto, perl utilizza internamente utf-8, in modo che il processo iniziale - test1.pl ha ricevuto direttamente dal Windows-1252utf-8. Quando chiamiamo un altro processo, dovremmo tornare alla code page Windows-1252?

+0

Si otterrebbero risposte molto più rapidamente se si fornisce codice minimo che mostri il problema. Se la descrivi semplicemente con le parole, c'è molto più che altro per l'immaginazione e la confusione. – daxim

+0

Come mai, nessuna delle dozzine di risposte che hai ricevuto per le sei domande che hai chiesto è stata sufficiente per essere accettata? –

+0

Sì, l'ho fatto ora. – Kartlee

risposta

8

Questo non ha nulla a che fare con la codifica di stringa interna di Perl, ma con la necessità di decodificare correttamente i dati provenienti dall'esterno. Fornirò il caso di test. Questo è Strawberry Perl 5.10 su un Windows XP europeo occidentale.

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; 

Esegui:

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

uscita (abbreviato):

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}"] 

Viene morso dal fatto che Windows utilizza una codifica diversa per l'ambiente di testo (IBM850) rispetto all'ambiente grafico (Windows-1252). Un esperto deve spiegare i dettagli più profondi di quel fenomeno.

Modifica:

E 'possibile euristico (il che significa che sarà in grado di fare la cosa giusta a volte, soprattutto per queste stringhe brevi) determinare codifiche. La migliore soluzione generica è Encode::Detect/Encode::Detect::Detector basata su Mozilla nsUniversalDetector.

Esistono alcuni modi per decodificare implicitamente dati esterni come open pragma/IO layers e -C switch, tuttavia essi gestiscono solo i flussi di file e gli argomenti del programma. A partire da ora, dall'ambiente deve essere decodificato in modo esplicito. Mi piace comunque, spiega esplicitamente che il programmatore di manutenzione ha pensato che il topic attraverso.

+0

Grazie daxim per la tua risposta. Poche domande - 1) È possibile determinare quale codifica viene utilizzata per la stringa proveniente da un mondo esterno? Ciò aiuterebbe a decodificare di conseguenza in perl. 2) Esiste un modo per istruire perl a gestire internamente la parte di decodifica piuttosto che da noi stessi determinando la codifica utilizzata nel mondo esterno? -Kartlee – Kartlee

+0

Grazie per il promemoria. L'ho fatto ora per quello che penso sia accettabile. – Kartlee

Problemi correlati