/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
YAML - UTF-8 ?!?
Fra : Morten P


Dato : 20-06-09 21:19

Jeg har haft store problemer med at mine UTF-8 YAML filer fik non-ascii
karakterer lavet om til "noget andet" [1].

Det samme skete hvis jeg skabte en fil med kun eet unicode tegn i og lod
perl læse det med 'open' og printe det.

Til sidst indså jeg at man kunne løse problemet ved at sætte binmode på
input handlet til filen.

YAML ser dog ikke ud til at kunne håndtere dette, så har ændret i sourcen
[2], hvorefter det fungerer fint.

Virker det som en rimelig modifikation eller kan jeg gøre noget andet og
smartere?



[1]
Før:

'comment' => 'LATIN SMALL LETTER U WITH DIAERESIS',
'binary' => '1111110',
'string' => 'ü'


Efter:

'comment' => 'LATIN SMALL LETTER U WITH DIAERESIS',
'binary' => '1111110',
'string' => "\x{fc}"




[2]
sub LoadFile {
my $IN;
my $filename = shift;
my $utf8 = shift; # ADDED
if (ref $filename eq 'GLOB') {
$IN = $filename;
}
else {
open $IN, $filename
or YAML::Base->die('YAML_LOAD_ERR_FILE_INPUT', $filename, $!);

# ADDED
binmode($IN, ':ut8')
if defined $utf8;
}
return Load(do { local $/; <$IN> });
}



 
 
Adam Sjøgren (20-06-2009)
Kommentar
Fra : Adam Sjøgren


Dato : 20-06-09 21:31

On Sat, 20 Jun 2009 22:18:54 +0200, Morten wrote:

> Jeg har haft store problemer med at mine UTF-8 YAML filer fik non-ascii
> karakterer lavet om til "noget andet" [1].

> Det samme skete hvis jeg skabte en fil med kun eet unicode tegn i og lod
> perl læse det med 'open' og printe det.

Har du sat din locale mærkeligt op? Kan du ikke prøve at vise et
minimalt eksempel på det med open()?

For mig ser det ud til at "roundtrip'e" fint:

$ perl -MYAML::Syck -MData::Dumper -e 'DumpFile("/tmp/test.yml", { test=>"Frække frølår" }); my $data=LoadFile("/tmp/test.yml"); print Dumper($data);'
$VAR1 = {
'test' => 'Frække frølår'
};
$ cat /tmp/test.yml
---
test: "Fr\xC3\xA6kke fr\xC3\xB8l\xC3\xA5r"
$

(LC_CTYPE=da_DK.UTF-8 og perl 5.10.0 hér).


Mvh.

Adam

--
"But they are all following you! Adam Sjøgren
No, they ain't, I'm just in front" asjo@koldfront.dk

Morten P (20-06-2009)
Kommentar
Fra : Morten P


Dato : 20-06-09 21:41

> Har du sat din locale mærkeligt op? Kan du ikke prøve at vise et

Det kan jeg ikke afvise

declare -x LANG="en_US.UTF-8"


> minimalt eksempel på det med open()?


1) Filen
--------

$ cat u.txt
ü


$ file -bi u.txt
text/plain; charset=utf-8


$ od -tx1 < u.txt
0000000 c3 bc 0a 0a
0000004


2) uden binmode
---------------

#!/usr/bin/perl

binmode ('STDOUT', ':utf8');

use strict;
use warnings;
use Data::Dumper;

open (FILE, 'u.txt') or die $^E;
my $u = join('', <FILE>);
print $u ."\n";
close (FILE);


$ perl test_suite/load_7bit.pl
ü



3) med binmode
---------------


#!/usr/bin/perl

binmode ('STDOUT', ':utf8');

use strict;
use warnings;
use Data::Dumper;

open (FILE, 'u.txt') or die $^E;
binmode(FILE, ':utf8');
my $u = join('', <FILE>);
print $u ."\n";
close (FILE);


$ perl test_suite/load_7bit.pl
ü



Det ser skørt ud hvis man spørger mig...





Adam Sjøgren (20-06-2009)
Kommentar
Fra : Adam Sjøgren


Dato : 20-06-09 22:15

On Sat, 20 Jun 2009 22:40:40 +0200, Morten wrote:

> #!/usr/bin/perl

> binmode ('STDOUT', ':utf8');

Hvorfor sætter du den?

> use strict;
> use warnings;
> use Data::Dumper;

> open (FILE, 'u.txt') or die $^E;
> my $u = join('', <FILE>);
> print $u ."\n";
> close (FILE);

> $ perl test_suite/load_7bit.pl
> ü

Jeg får:

$ echo 'ü' > u.txt
$ cat u.txt
ü
$ hexdump u.txt
0000000 bcc3 000a
0000003
$ perl -MFile::Slurp -e 'my $txt=read_file "u.txt"; print $txt;'
ü
$ perl -MFile::Slurp -e 'my $txt=read_file "u.txt"; print $txt;' | hexdump
0000000 bcc3 000a
0000003
$

Men hvis jeg laver dit "sæt binmode :utf8 på STDOUT"-trick, så får jeg:

$ perl -MFile::Slurp -e 'my $txt=read_file "u.txt"; binmode "STDOUT", ":utf8"; print $txt;'
ü
$ $ perl -MFile::Slurp -e 'my $txt=read_file "u.txt"; binmode "STDOUT", ":utf8"; print $txt;' | hexdump
0000000 83c3 bcc2 000a
0000005
$

Så ska' du ikke bare lade være med det og så virker det?


Mvh.

Adam

--
"En fjern transistor stiller ind på Kalundborg" Adam Sjøgren
asjo@koldfront.dk

Adam Sjøgren (20-06-2009)
Kommentar
Fra : Adam Sjøgren


Dato : 20-06-09 22:32

On Sat, 20 Jun 2009 23:21:56 +0200, Morten wrote:

> "Adam "Sjøgren"" <asjo@koldfront.dk> wrote in message
> news:87eite38vx.fsf@topper.koldfront.dk...
>> On Sat, 20 Jun 2009 22:40:40 +0200, Morten wrote:

>>> binmode ('STDOUT', ':utf8');

>> Hvorfor sætter du den?

> For ellers fungerer det ikke

Du viste ikke hvad der sker når du fjerner den?

> Se de to eksempler hvor det eneste der adskiller sig er brugen af
> binmode eller ej og dermed output.

Ja, om du sætter binmode på FILE eller ej.

Forskellen mellem dine eksempler og mine er at det der virker for mig,
sætter jeg _overhovedet_ ikke sætter binmode, altså heller ikke på
STDOUT.

>>> $ perl test_suite/load_7bit.pl
>>> ü

> Det er uden binmode.

På FILE, men _med_ på STDOUT!

> Det kunne være at jeg alligevel ikke har et helt rent ut-8 miljø...

Måske...


Mvh.

--
"My brain always rejects attitude transplants." Adam Sjøgren
asjo@koldfront.dk

Adam Sjøgren (20-06-2009)
Kommentar
Fra : Adam Sjøgren


Dato : 20-06-09 22:35

On Sat, 20 Jun 2009 23:25:10 +0200, Morten wrote:

> Hvis jeg ikke sætter den, så får jeg mærkelige tegn i putty:

> "ogs¦"

Måske din putty er fejlkonfigureret?

>> Se de to eksempler hvor det eneste der adskiller sig er brugen af binmode
>> eller ej og dermed output.

> binmode her er helt nede i YAML koden.

Den er jeg med på, men det virker som om problemet er langt tættere på
dig end YAML-modulet, derfor prøvede jeg at blande det udenom indtil vi
har det på det rene.


Mvh.

--
"No more than that, but very powerful all the same; Adam Sjøgren
simple things are good." asjo@koldfront.dk

Søg
Reklame
Statistik
Spørgsmål : 177414
Tips : 31962
Nyheder : 719565
Indlæg : 6407824
Brugere : 218875

Månedens bedste
Årets bedste
Sidste års bedste