Perl i UTF + Locale¶
Czasami ja nie rozumiem jak działa Perl, dziś jest jeden z takich dni:
Oba kody robią to samo, jeden z localami drugi bez:
Code 1 - test.pl¶
#!/usr/bin/perl
use utf8;
use warnings;
use strict;
use locale;
#use POSIX q(setlocale);
#setlocale(&POSIX::LC_ALL, "pl");
# Uzywamy funkcji do kodowania/dekodowania
# utf8::encode($string);
# utf8::decode($string);
die "$0 testfile.txt" if scalar @ARGV <= 0;
# pobieram caly plik
open( FH, '<', $ARGV[0] ) or die "Error: usage $0 file\n\n";
my $txt = do { local ($/); };
close(FH);
utf8::decode($txt);
my @words = $txt =~ m/\w+/g;
map { utf8::encode($_) } @words;
print join(", ", @words)."\n";
Code 2 - test2.pl¶
#!/usr/bin/perl
use utf8;
use strict;
use warnings;
#use locale;
#use POSIX q(setlocale);
#setlocale(&POSIX::LC_ALL, "pl");
use open ':encoding(utf8)';
#use open ':locale';
die "$0 testfile.txt" if scalar @ARGV <= 0;
# pobieram caly plik
open( FH, '<', $ARGV[0] ) or die "Error: usage $0 file\n\n";
# tak samo jak use open 'encoding...'
#binmode FH, ":encoding(utf8)";
my $txt = do { local ($/); };
close(FH);
my @words = $txt =~ m/\w+/g;
map { utf8::encode($_) } @words;
print join(", ", @words)."\n";
Wyniki:¶
$ locale
LANG=pl_PL.UTF-8
LC_CTYPE="pl_PL.UTF-8"
LC_NUMERIC="pl_PL.UTF-8"
LC_TIME="pl_PL.UTF-8"
LC_COLLATE="pl_PL.UTF-8"
LC_MONETARY="pl_PL.UTF-8"
LC_MESSAGES="pl_PL.UTF-8"
LC_PAPER="pl_PL.UTF-8"
LC_NAME="pl_PL.UTF-8"
LC_ADDRESS="pl_PL.UTF-8"
LC_TELEPHONE="pl_PL.UTF-8"
LC_MEASUREMENT="pl_PL.UTF-8"
LC_IDENTIFICATION="pl_PL.UTF-8"
LC_ALL=
$ cat input.txt
ęł@ąóąłð
łąśk
ala_ma_kota
$ perl test.pl input.txt
ęł, ą, ął, łąśk, ala_ma_kota
$ perl test2.pl input.txt
ęł, ąóąłð, łąśk, ala_ma_kota
Tak na moje oko wyniki ze skryptu numer 2 są poprawne, ale dlaczego? Heh, czyżby ustawienie locali twierdziły, że ó nie jest litera słowa?
No nie ważne, zapewne jakimś rozwiązaniem mogło by być ustawienie:
use POSIX qw(locale_h);
setlocale(LC_ALL,"pl_PL.UTF8");
ale mi się tego robić nie chciało :)
Znalazłem tutorial o perlu i polskich znakach,
może komuś pomoże - ja go nie stosowałem - w zupełności wystarczyła mi pragma use utf8;
.