簡単で、ポータブルでなくて、低速な、国際化ドメイン変換モジュール
国際化ドメインをエンコード、デコードしたい。CPAN シェルを使ってインストールできるモジュールはなさそう (Punycode の encode/decode はどのモジュールを使えばいいのか考える修行 - 昨日知ったこと) なので自分で Pure Perl なモジュールを書かないとかな、とか考えている。が、とりあえず使えるものとして、idn コマンドを使ったスクリプトを書いてみた。(このブログエントリのタイトルは「変換モジュール」となっているが、書いたものはパッケージではあるけれどモジュールじゃないな、と)
use strict; use warnings; package Unau::IDN; use Encode qw//; sub new { my ($class) = @_; # use FileHandle; # use IPC::Open2; # $ my $pid = open2(*Reader, *Writer, 'nl'); # Writer->autoflush(1); # print Writer "this is a test\n"; # my $line = <Reader>; # print "$line"; bless {}, $class; } sub decode { my ($self, $in) = @_; idn_decode($in); } sub encode { my ($self, $in) = @_; idn_encode($in); } sub idn_decode { my $in = shift; open my $fh, "echo $in | idn -u --quiet |" or die $!; chomp(my $out = <$fh>); Encode::decode_utf8($out); } sub idn_encode { my $in = shift; open my $fh, "echo $in | idn -a --quiet |" or die $!; chomp(my $out = <$fh>); Encode::decode_utf8($out); } 1; package main; use Test::More tests => 3; use Encode; use utf8; my $idn = new Unau::IDN; while (my $line = <DATA>) { chomp($line); my ($direction, $str, $expected) = split(q{/}, $line); my $actual = $direction eq 'dec' ? $idn->decode($str) : $idn->encode($str); is($expected, $actual, encode_utf8("$str -> $expected")); } __DATA__ dec/xn--dhqu55a2taf8b.jp/小島丈幸.jp enc/暴走小判.jp/xn--fcrq5vtzijn4b.jp enc/MajiでKoiする5秒前.org/xn--majikoi5-783gue6qz075azm5e.org
実行結果。
[takeyuki@sunya ~]$ perl aa.pl 1..3 ok 1 - xn--dhqu55a2taf8b.jp -> 小島丈幸.jp ok 2 - 暴走小判.jp -> xn--fcrq5vtzijn4b.jp ok 3 - MajiでKoiする5秒前.org -> xn--majikoi5-783gue6qz075azm5e.org