2012-06-13 7 views
6

Hai điểm bắt đầu:Đúng là chuyển đổi IO của perl mặc định thành utf-8 trong khi sử dụng Plack và Middlewares?

  • Trong his answer to Why does modern Perl avoid UTF-8 by default? tchrist chỉ ra 52 điều cần thiết để đảm bảo chính xác Unicode xử lý trong Perl. Câu trả lời cho thấy mã soạn sẵn với một số câu lệnh use. Câu hỏi tương tự về việc sử dụng Unicode là How to make "use My::defaults" with modern perl & utf8 defaults?
  • PSGI spec theo định hướng byte thiết kế. Đó là trách nhiệm của tôi để mã hóa/giải mã tất cả mọi thứ, vì vậy cho Plack ứng dụng một cách chính xác là để mã hóa đầu ra và giải mã đầu vào, ví dụ:

    use Encode; 
    my $app = sub { 
        my $output = encode_utf8(myapp()); 
        return [ 200, [ 'Content-Type' =>'text/plain' ], [ $str ] ]; 
    }; 
    

Là nó đúng để sử dụng

use uni::perl; # or any similar 

trong ứng dụng PSGI và/hoặc trong các mô-đun của tôi?

uni::perl thay đổi mặc định Perl của IO sang UTF-8, như sau:

use open qw(:std :utf8); 
binmode(STDIN, ":utf8"); 
binmode(STDOUT, ":utf8"); 
binmode(STDERR, ":utf8"); 

Will làm như vậy phá vỡ một cái gì đó trong Plack hoặc middlewares của nó? Hoặc là cách chính xác để viết ứng dụng cho Plack mã hóa/giải mã một cách rõ ràng khi mở, vì vậy không có open pragma?

+1

Plack có ghi vào STDOUT hoặc đọc từ STDIN không? Nếu vậy, nó gần như chắc chắn sai (trừ khi họ cũng là một lỗi trong Plack). Tôi nói "gần như" vì việc sử dụng 'binmode' trong Plack sẽ khiến nó không quan tâm. PS - bây giờ bạn biết tại sao nó không được thực hiện theo mặc định; nó phá vỡ công cụ. – ikegami

+0

Tôi hy vọng hơn @miyagawa gurusan sẽ nói thêm .. :) Và tôi hiểu tại sao utf8 không phải là mặc định, nhưng, (IMO) các mô-đun CPAN mới nên được phát triển với "perl -CSDA" hoặc với 'env PERL_UNICODE' trong tâm trí. Và miyagawa chắc chắn sử dụng nó trong môi trường Nhật Bản, vì vậy, nên biết đúng cách ..;) – cajwine

+0

Tôi nghĩ rằng "đúng cách" bạn danh sách bị hỏng. 'text/plain' cần một bộ ký tự để phía bên kia biết những byte nào đại diện và cách giải mã chúng. – Ashley

Trả lời

2

Bạn thực sự không muốn đặt STDIN/STDOUT thành chế độ UTF-8 theo mặc định trên Plack, bởi vì bạn không biết ví dụ cho dù chúng có phải là dữ liệu nhị phân hay không. Ví dụ. nếu những tập tin đó là trình kết nối giao thức FastCGI, chúng sẽ mang các cấu trúc nhị phân được mã hóa chứ không phải văn bản UTF-8. Do đó, chúng không được xác định một lớp mã hóa hoặc các cấu trúc nhị phân đó sẽ bị xáo trộn hoặc bị từ chối là không hợp lệ.

-1

Trên hệ thống GNU/Linux hiện đại, bạn hoàn toàn nên chuyển sang UTF-8 trên toàn cầu. Điều này có nghĩa thiết

LANG="xx_YY.UTF-8" 
PERL_UNICODE=SDAL 
PERL5OPT=-Mutf8 

trong /etc/environment hoặc /etc/sysconfig/i18n hoặc /etc/default/locale hoặc bất cứ tập tin cấu hình hệ thống của bạn. Bởi vì RHEL/Centos bug Tôi đã liên kết tượng trưng /etc/environment đến sysconfig/i18n.

Tập lệnh dựa vào đầu vào nhị phân phải đặt binmode trên STDIN/OUT/ERR (?) Hoặc use open pragma hoặc phải được gọi với tùy chọn -C0.

Vấn đề là một số trình điều khiển DBD bị lỗi, ví dụ: DBD::JDBC và bạn phải đặt cờ utf8 bằng tay.

use Encode qw/_utf8_on/; 
map { _utf8_on $_; } @strings;