2009-07-02
■Encode::JP::Emojiでの相互変換
utf8(docomo) ↓ sjis(kddi)
ってやる方法は、
utf8(docomo) ↓ x-sjis-emoji-docomoでencode sjis(docomo) ↓ x-sjis-e4u-docomoでdecode utf8(google) ↓ x-sjis-e4u-kddiでencode sjis(kddi)
のようにするので合ってるかな?かな?
つまりは相互変換するときはGoogleのUTF-8を経由しないといけないということなんだろうか?
実際以下のコードだと動くのでそうなのかな。
use Encode::JP::Mobile; use Encode::JP::Emoji; my $kddi = "\xF6\x59"; my $docomo = "\xF9\xDC"; # Encode::JP::Mobile warn $kddi eq encode( 'x-sjis-kddi-auto', decode( 'x-sjis-imode', $docomo ) ); # true # Encode::JP::Emoji my $docomo_str = decode( 'x-sjis-emoji-docomo', $docomo ); my $docomo_octet = encode( 'x-sjis-emoji-docomo', $docomo_str ); my $google_str = decode( 'x-sjis-e4u-docomo', $docomo_octet ); warn $kddi eq encode( 'x-sjis-e4u-kddi', $google_str ); # true
追記:
↓これでもできるようですね。
warn $kddi eq encode( 'x-sjis-e4u-kddi', decode( 'x-sjis-e4u-docomo', $docomo ) ); # true
■Encode::JP::Emojiをつかってみて思ったこと
これはイイとおもって実践で使えるかどうか考えてる間に思ったことをつらつら書きます。
- 相互変換する際に encode( 'x-sjis-e4u-kddi', decode( 'x-utf8-e4u-docomo', $str ) ) ってやるんだけど decode() でキャリアの指定が必要なようだ。
- つまり$strがどのキャリアから入力されたものであるかを知ってないといけない。(Encode::JP::Mobileだと、そこをutf8とかでいける)
- なるほど、$strをDBなどに持つ場合はキャリアのutf8の文字コードではなくGoogleが提案しているコードポイントでの保存することが前提のモジュールになっているようだ。
- Googleの提案しているコードポイントはまだ正式にUnicodeに入ってないので、現時点でDBにGoogleのコードポイントのやつを保存するのはちょっと躊躇われるかも。
流れ的に正しいし便利だなーと思ったのですがUnicodeに入るのが前提かなぁ。
まぁ思い切ってGoogleのコードポイントでDBに入れちゃってもいいきもするけど。
実装みたらtrを使って置換してるんですね。すげー。
2009-05-29
■emacs lispのshell-command-to-string()
shell-command-to-stringっていう関数は、渡された文字列をコマンドとしてログインシェルに渡すっぽい。
なのでtcshをログインシェルにしていて、下記のようなものを評価すると
(shell-command-to-string
"perl -e 'print join(q{ }, grep( !/^\.$/, @INC));'"
)
"/: Event not found.
"
エラーがでます。これは「!」がtcshでは特別な意味を持ってるから。
ログインシェルをbashやzshに変えてやってみたら↑のは問題なく実行できました。
2009-05-20
■XSをモジュールなしでロードするには?
よくわかってないんだけど、とりあえず動いたので忘れないようにメモ。
(ただしこれはOSX上でのことなので他のOSだとところどこパスなどで違う部分があると思う)
1. hoge.xsを作る
今回は単純にパッケージ名をPACKAGENAMEで、メソッド名methodnameというのが1つあるだけのhoge.xsだとする。
2. xsubppというコマンドでhoge.xsをhoge.cに変換する
typemapが必要なのでExtUtilsのパッケージの中のを使う。
% xsubpp -typemap /System/Library/Perl/5.8.8/ExtUtils/typemap hoge.xs > hoge.c
3. hoge.cをコンパイルする前にppport.hというのを生成しておく
% perl -MDevel::PPPort -e 'Devel::PPPort::WriteFile()'
4. hoge.cをコンパイルする
コンパイルにはEXTERN.hとかが必要なので、下記のような適当な場所をコンパイルオプションに追加する。これでhoge.oができる。
% gcc -I/System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE -c hoge.c
5. hoge.oをhoge.bundleにする
gcc -bundle -undefined dynamic_lookup -L/usr/local/lib -bundle hoge.o -o hoge.bundle
6. Perlからhoge.bundleをロードする
以下のようにDynaLoaderの関数を使ってxsで書いたパッケージのメソッドを呼び出すことができる。
#!/usr/local/bin/perl
use strict;
use warnings;
use DynaLoader;
my $libref = DynaLoader::dl_load_file( '/path/to/hoge.bundle' );
my $symref = DynaLoader::dl_find_symbol($libref, 'XS_PACKAGENAME_methodname');
DynaLoader::dl_install_xsub('methodname', $symref);
methodname();
まぁ、こんな感じで動くのは確認したんだけど、そもそものxsubppでなにやってるのかとかDynaLoaderでこうやるとメソッドが呼べるとかの原理は詳しく調べてないので、その辺はあとで調べる。
とりあえず今日はここまで。
■ap_getword()の動作
Apacheのhttpd.hに定義があるap_getword()は、第二引数で渡したポインタの位置から読んでいって最初に第三引数が発見されるまでの文字列のポインタを返す。
const char *uri = "/foo/bar/baz.jpg"; const char *dir; uri++; // uri = foo/bar/baz.jpg dir = ap_getword(r->pool, &uri, '/'); // uri = bar/baz.jpg, dir = foo uri--; // uri = /bar/baz.jpg

