Rabbit Slide Show

nadoka さんの m17n 対応のベストプラクティス

2012-09-15

Description

IRCnet の日本語チャンネルでは iso-2022-jp が使われていて、 iso-2022-jp は ascii compatible ではありません。 そのことが様々な問題を引き起こします。 その問題をどう解決したのか、 nadoka さんでの m17n 対応の最善の方法は何なのか、 ということについて話をする予定です。

Text

Page: 1

nadoka の ruby 1.9 対応
⻄⼭和広
2012/09/15
Powered by Rabbit 2.0.5

Page: 2

自⼰紹介
CRuby のコミッターのひとり
https://github.com/nadoka のメンバー
大阪から来ました
札幌は涼しいかと思いきや...
1/18

Page: 3

IRC とは?
インターネット経由の複数⼈でのチャット
1対1ではない
IRC = Internet Relay Chat
古くからあるのでいろいろな環境で使える
Ruby の開発でも使われている
IRCnet の #ruby-ja (⽇本語)
freenode の #ruby-core (英語)
2/18

Page: 4

nadoka とは?
正式名称は nadoka さん
IRC Client Server Program
proxy のようなもの
plugins (bot) 対応
3/18

Page: 5

plugins (bot) の例
自動応答系
Google 検索
URL からタイトル取得
天気情報取得
⼈⼯無能
自動発⾔系
RSS の情報通知
挨拶
時報
4/18

Page: 6

ruby 1.9 での問題
発⾔がみえなかった
発⾔ができなかった
など
5/18

Page: 7

ここか
ら本題

Page: 8

使用 encoding
⽇本語圏では主に以下の encoding を使用
IRCnet : いわゆる JIS コード (ISO-2022-JP)
freenode : UTF-8
問題
valid (valid̲encoding? が真) とは限らない
クライアントの設定ミス
いわゆる半角カナの扱い
7/18

Page: 9

nadoka 本体への⼊出⼒
server や client との送受信
invalid なものもそのまま通したい
エラー処理は server や client に任せた
い
⽂字化けの原因になりたくない
内部処理や plugins との⼊出⼒
元のバイト列そのまま
必要なら plugins で変換
8/18

Page: 10

nadoka 本体での扱い
⽅針 : nadoka 本体では ASCII-8BIT で扱う
force̲encoding(Encoding::ASCII̲8BIT) 
でバイナリ⽂字列扱い
⽂字列の内容は変換しない
ruby 1.8 との互換性も考慮したため
9/18

Page: 11

plugins の encoding 問題
encoding の扱いが
plugin によってバラバラ
ruby 1.8 では適当でも動いた
ruby 1.9 では
Encoding::CompatibilityError 例外頻出
たとえば
複数回 nkf を通していたり
ISO-2022-JP と正規表現マッチしていたり
10/18

Page: 12

plugins の encoding ⽅針
受信時に
⼀回だけ UTF-8 に変換
内部処理
UTF-8 で統⼀
EUC-JP や Shift̲JIS で扱っていた plugin も変
更
/re/e や /re/s で混在していた
送信時に
⼀回だけ server encoding に変換
11/18

Page: 13

問題例 (1)
String#force̲encoding(enc) を定義
self を返すだけ
ruby 1.8 + 別のライブラリ 
(nokogiri-1.5.2) の内部で謎のエラー
uninitialized constant 
Nokogiri::XML::Node::Encoding
実は ::Encoding を参照しようとしていた
respond̲to?(:force̲encoding) で確認し
てから使うように変更
12/18

Page: 14

問題例 (2)
nadoka 本体
サーバーへ送信する⽂字列を作成する部分
チャンネル名 (ASCII-8BIT) + 発⾔内容 
(JIS)
ruby 1.8 だと気にせず結合できていた
ruby 1.9 だと両⽅ ASCII only でも例外 
Encoding::CompatibilityError
ISO-2022-JP が ascii̲compatible? では
ないため
発⾔内容を force̲encoding して解決
13/18

Page: 15

問題例 (3)
plugin からの発⾔例
bot 名: "hello bot: "
発⾔内容: "こんにちは"
bot名 (UTF-8) + 発⾔内容 (JIS)
発⾔内容⽣成時に tojis で変換済み
結合時に例外 Encoding::CompatibilityError
結合後にも tojis で変換
ruby 1.8 だと nkf の自動認識で問題なし
ruby 1.9 だと結合後の tojis まで来ない
14/18

Page: 16

問題例 (3) の解決⽅法
bot名 (UTF-8) + 発⾔内容 (UTF-8)
発⾔内容⽣成時には変換しない
tojis で全体を変換
nadoka 本体に渡す直前で⼀度だけ変換すべき
15/18

Page: 17

まとめ
String#force̲encoding を定義して⼿抜き 
1.8/1.9 両対応は不幸の元
ISO-2022-JP が US-ASCII 互換ではないの
でバグが発⾒できた
無駄に複数回変換しない
それぞれの⼊⼒、出⼒部分だけで変換すべき
nkf 便利
16/18

Page: 18

おまけ
trunk で動かしたら問題発⽣
17/18

Page: 19

ruby 2.0 対応
iconv がなくなっている
1.8 も考慮して nkf で置き換える?
String#encode にするかどうかは未定
Powered by Rabbit 2.0.5
18/18

Other slides