トミールの技術系日記

忍たまはじめました

Encode::UTF8Mac

探したのだけど作っている人がいなかったので、いわゆるutf-8-macと呼ばれるエンコーディングを追加するEncode::Encodingをつくりました。

https://github.com/tomi-ru/Encode-UTF8Mac

use Encode;
use Encode::UTF8Mac;

print Encode::encode('utf-8-mac', '蘄藭づけ');

use Path::Class;
for my $entry (dir(".")->children) {
    my $filename = Encode::decode('utf-8-mac', $entry);

}

反応みてPODちゃんと書いたらUPしようと思っている

→POD書いた. PODの方が少し整理されているのでわかりやすいかもしれない。

https://github.com/tomi-ru/Encode-UTF8Mac/blob/master/README

Macのファイル名はNFDされている

MacOSXでは文字コードutf-8エンコーディングが使われているのだけど、UnicodeのNFDという正規化がされている。

具体的には、「だ」みたいな濁点つきカナが、「た」+「゛」の二つのUnicodeで表現されたりしてる。゛は「てん」で変換してでる濁点マーク(U+309B)ではなく、Unicodeで組み合わせる用として用意されている点(U+3099)。

ふつうにdecode('utf-8')すると「だ」が一文字じゃなく2つのUnicode、つまりlengthが2になるわけです。

なので、perlではファイル名はをdecodeしたあとUnicode::NormalizeのNFC関数(NFCは「た」+「゛」的なものを「だ」と扱う正規化名)を使ってくっつけるという方法が使えます。

use Encode;
use Unicode::Normalize;

my $filename = Encode::decode('utf-8', $filename);
$filename = Unicode::Normalize::NFC($filename);

ちなみにファイルやディレクトリを作成する時は、NFDな(「だ」のようにくっついた)ものをわたしても、Mac側で勝手にNFCします。逆に言うと、ファイルシステムに出す時はNFD化して出す、ということはしなくてもいい。(けど作ったモジュールはencode時ちゃんとNFDしてる)

utf-8-macとは

ところが、UnicodeNFCは「た」+「゛」→「だ」のようなそのままのものだけではなく、「蘄」を「福」とする、などの正規化も行なってしまいます。

Macでは「蘄」は使えないのか?というとそんなことはない。じゃあMacはどうしてるのかというと、特定の範囲はNFDしない、という特例付きでNFDしています。

http://developer.apple.com/library/mac/#qa/qa2001/qa1173.html

「HFS Plus は、Normal Form D の変形を使用しており、U+2000 から U+2FFF、U+F900 から U+FAFF、および U+2F800 から U+2FAFF は分解されません」

http://www.unicode.org/charts/PDF/U2000.pdf
http://www.unicode.org/charts/PDF/UF900.pdf
http://www.unicode.org/charts/PDF/U2F800.pdf

perlutf-8-macなdecodeをしたい

じゃこれを判断して'蘄藭づけ.txt'みたいなファイルを'福神づけ.txt'じゃなくちゃんと'蘄藭づけ.txt'とdecodeするにはどうしたらよいかというと、osxに付属のiconvは独自に'utf-8-mac'というエンコーディングを使えるようにしてるらしく、それで変換すればいいらしい。

ただこれだけのために日ごろ使うことないText::Iconv使いたくないなあと。

そこで、特例の範囲をのぞいてNFC/NFDするエンコーディングを作りました。

なんで誰もつくってないんだ??!とおもったのですが、実際は、これら特例の範囲はほぼ超難しい漢字とかだけなので、影響するのはアジア圏の一部、ということで上記のUnicode::Normalize::NFC作戦でほぼ問題はないということから作られてなかったのかもしれないですね。

これがあれば、ファイル名を出し入れする時にEncodeのみでいけるので、使うエンコーディングは、日本語の場合こんな感じにするだけでよくなるんじゃないかと思います。

$encoding = do {
    if ($^O eq 'MSWin32') {
        'cp932',;
    } elsif ($^O eq 'darwin') {
        'utf-8-mac';
    } else {
        'utf-8';
    }
};

そんな時間あったら

原稿すすめなきゃって話だな。

気づいたちょっとしたバグとかtypoはわかる人には連絡したりします、本当はパッチとか送ればいいんだけど

書いてる時にきづいたことで

本文に載せないこと書いていこうかな

tig.rbからtwitterircgatewayへ

はるかに安定してる。

グループ機能がべんりすぎる

twitterircgateway から tig.rb へ(つづき

その後、SSLがどうたらってエラーでてたのですが、適当にみつけたここのやり方でca_fileを追加した。

http://d.hatena.ne.jp/sugyan/20100208/1265559679

あと、リスト機能いらないので適当に消したり。ここで思ったんだけど(遅い)、tig.rbはあくまでNet::IRCモジュールのサンプルスクリプトなのですよね。何か機能を足したり減らしたりしたい場合、プラグイン的なもので外から変更できる漢字じゃないからtig.rbを書き直したりしないといけない。むう。自分専用だしいっか。

というわけで他にも、タイムラインがおおすぎるのを調整するために check_timeline 内をごにょごにょした。

twitterircgateway から tig.rb へ

公式RTやoauthに対応してそうなので変えてみることにした。

以下、ひさしぶりにrubyさわった記録。ひごろさわらない言語さわるとへんなところでつまづくのが新鮮でたのしい。

git clone git://github.com/cho45/net-irc.git
cd  net-irc
$ ruby ./examples/tig.rb --debug

おおう、このマシンrubyはいってないわwww

sudo yum install ruby
ruby ./examples/tig.rb --debug

jsonモジュールねーよ的なエラー。ぼくしってるcpanじゃなくてgemていうんでしょrubyの世界では。local::lib的なのしらないからシステムエリアにいれちまうぜよ

sudo yum install rubygems
sudo gem install json

ヘッダファイルねーよ的な。はいはい。

sudo yum install ruby-devel
sudo gem install json
sudo em install oauth
ruby ./examples/tig.rb --debug

oauth ruby uninitialized constant Digest::Class (NameError) 的なエラー。なんか初歩的ミスしてるにおいがするぜ。適当にググったら0.4.1じゃなくて0.3.6にすればいいよとか。エー。それって解決って言わないんじゃ・・・

と思って本家のページ見に行くと http://oauth.rubyforge.org/ 「0.3.6」! とデカデカと出ていてstableぽい。なんだよgem。

sudo rm /usr/lib/ruby/gems/1.8/gems/oauth-0.4.1/
cd /tmp
wget http://rubyforge.org/frs/download.php/63653/oauth-0.3.6.gem
gem install oauth-0.3.6.gem
ruby ./examples/tig.rb --debug

こんどはjsonでundefined symbol: RSTRING_PTRとかエラー。これもなんだか初歩的ミスの雰囲気が。yumで入った1.4.3は最新らしいのだが、とりあえずgitの最新版をいれてみる。

git clone http://github.com/flori/json.git
cd json
sudo install.rb
sudo rm /usr/lib/ruby/gems/1.8/gems/json-1.4.3/
ruby ./examples/tig.rb --debug

なんとなくinstall.rbたたいて欲しそうなのでinstall.rb の中身もみずに叩いてみる。どうせ自分用サーバーの自分用twitterゲートウェイだしな。このへん、後輩ならふつうにmake使うとか既存の知られたルールにのったったほうが受け入れられやすいんじゃないのって思うが気にしない。

うごいたぽい

ruby ./examples/tig.rb --help
less /etc/sysconfig/iptables
ruby ./examples/tig.rb --port=xxxx --host=* --debug

とりあえず開いてるポートで立ち上げて、普通にtiarraからじゃなくて外からつないでみる。nickにtwitterID、パスワードにtwitterパスワードね。

oauthURLと、/me oauthしろと出る。してもうまくいかない。

あそうか。#twitterチャンネルに入らないとだめか。#twitterチャンネルで /me oauth 数字 したらうまくいった。

公式RTを生かすには、、、./examples/tig.rb をななめ読むとwith_retweetsを設定するらしい。設定は、接続時の名前(ニックじゃなくて名前いれるところ)に tomita with_retweets みたいにスペース空けて入れろということかな。

うまくいかない。

limechatは名前欄のスペースを取っちゃうみたいで、tomitawith_retweetsになるんだよね。

そこでtiarraからやってみる。

t {
    host: localhost
    port: xxxxxxxx
    nick: tomita
    name: tomita with_retweets
    password: xxxxxxx
}

おー、いった。リサイクルマークwww

18:24(hasegawayosuke)10♺ RT @monjudoh: 正義なんて不毛だ