Recommended
PDF
PDF
PDF
Richard high performance fuzzing ja
PDF
PDF
PDF
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
PDF
PPTX
PPT
YAPC Asia 2010 30days Albumの裏側 後日談
PPT
関西オープンソース 2008 30days Albumの裏側
PPT
PDF
PPTX
ConfD で Linux にNetconfを喋らせてみた
PDF
Infinite Debian - Platform for mass-producing system every second
PDF
PDF
Cli mini Hack!#1 ~Terminalとの親睦を深めよう~
PPTX
PPTX
Dockerと外部ルータを連携させる仕組みを作ってみた
PDF
PDF
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
PDF
PDF
Scapy presentation Remake(訂正)
PDF
PDF
PPTX
攻撃者の行動を追跡せよ -行動パターンに基づく横断的侵害の把握と調査- by 朝長 秀誠, 六田 佳祐
PDF
Lisp Tutorial for Pythonista Day 6
PDF
PPTX
HDFSネームノードのHAについて #hcj13w
PDF
PDF
More Related Content
PDF
PDF
PDF
Richard high performance fuzzing ja
PDF
PDF
PDF
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
PDF
PPTX
What's hot
PPT
YAPC Asia 2010 30days Albumの裏側 後日談
PPT
関西オープンソース 2008 30days Albumの裏側
PPT
PDF
PPTX
ConfD で Linux にNetconfを喋らせてみた
PDF
Infinite Debian - Platform for mass-producing system every second
PDF
PDF
Cli mini Hack!#1 ~Terminalとの親睦を深めよう~
PPTX
PPTX
Dockerと外部ルータを連携させる仕組みを作ってみた
PDF
PDF
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
PDF
PDF
Scapy presentation Remake(訂正)
PDF
PDF
PPTX
攻撃者の行動を追跡せよ -行動パターンに基づく横断的侵害の把握と調査- by 朝長 秀誠, 六田 佳祐
PDF
Lisp Tutorial for Pythonista Day 6
PDF
PPTX
HDFSネームノードのHAについて #hcj13w
Similar to Rubyのエンコーディング
PDF
PDF
PDF
PDF
PDF
nadoka さんの m17n 対応のベストプラクティス
PDF
PDF
PPTX
PDF
PPTX
PDF
PDF
Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)
PDF
Unicodeについて教えてgooでしつこくきいてみたよ♪
PDF
PDF
PPTX
A Reintroduction To Ruby M17 N
PDF
PDF
PDF
PDF
Reading Self-descriptive FizzBuzz
More from Masahiro Tomita
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
「理論から学ぶデータベース実践入門」読書会スペシャル
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
Rubyのエンコーディング 1. Rubyのエンコーディング
NSEG#30
とみたまさひろ
2012-08-25
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
2. 自己紹介
✓ とみた まさひろ (ペンネーム)
✓ プログラマー (Ruby & C)
✓ http://d.hatena.ne.jp/tmtms
✓ http://twitter.com/tmtms
✓ 好きなもの
✓ Ruby, MySQL, Ubuntu, Emacs, Git
1/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
3. NSEG
✓ #1 Rubyの黒魔術
✓ #3 はじめてのRuby拡張ライブラリ
✓ #6 Ruby紹介
✓ #11 RSpecとCucumber
✓ #13 システムコール
✓ #14 MySQLの文字コード
✓ #18 Rabbit
✓ #20 TDDについて
✓ #21 Linuxのメモリ
Rubyのエンコーディング - NSEG#30
2/45
Powered by Rabbit 1.0.9
4. Ruby 1.8
は
オワコン
Rubyのエンコーディング - NSEG#30
3/45
Powered by Rabbit 1.0.9
5. 1.8.7の今後につきまして
✓ 2012年6月まで、通常のメン
テナンスが続きます。
✓ それ以降、バグフィックスリリー
スは終了いたします。2013年
6月まではセキュリティフィック
スは続けますので、それまでは
1.8.7をお使いいただけます。
✓ 2013年6月より先は、1.8.7
はあらゆるサポート対象外に
なります。
http://www.ruby-lang.org/ja/news/2011/10/07/plans-for-1-8-7/ 4/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
6. Ruby 1.9
を使いまし
ょう
Rubyのエンコーディング - NSEG#30
5/45
Powered by Rabbit 1.0.9
7. 1.9の
特徴
Rubyのエンコーディング - NSEG#30
6/45
Powered by Rabbit 1.0.9
8. 一番大きい
のはエンコ
ーディング
Rubyのエンコーディング - NSEG#30
7/45
Powered by Rabbit 1.0.9
9. Rubyのエンコーディング
http://d.hatena.ne.jp/tmtms/20120812/ruby_encoding
8/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
10. エンコーディング?
✓ 文字符号化方式
✓ UTF-8 とか EUC-JP とか SHIFT_JIS とか
そーゆー奴
✓ charset とか呼ばれたり
✓ いわゆる「文字コード」
9/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
11. 同じ文字でも異なるコード
「あ」
✓ UTF-8 では 0xE3 0x81 0x82 の3バイト
✓ EUC-JP では 0xA4 0xA2 の2バイト
✓ SHIFT_JIS では 0x82 0xA0 の2バイト
10/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
12. 同じバイト列でも別の文字
0xC2 0xA9 の2バイトは
✓ UTF-8 では「©」1文字
✓ EUC-JP では「息」1文字
✓ SHIFT_JIS では「ツゥ」2文字
11/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
13. Ruby 1.8.x
✓ "xC2xA9" という文字列は Ruby 的にはた
だのバイト列
✓ エンコーディング情報を持たない
✓ "©"(UTF-8) として扱うか "息"(EUC-JP) とし
て扱うかはプログラム次第
12/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
14. Ruby 1.9.x
✓ 文字列のエンコーディングは文字列自身が知
っている
✓ "©"(UTF-8) と "息"(EUC-JP) は同じバイト列
だけど異なる文字列
✓ "あ"(UTF-8) と "あ"(EUC-JP) は同じ文字を表
してるけど等しくない
✓ 同じプログラム中で複数のエンコーディングの
文字列を同時に扱える(珍しいかも)
13/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
15. ちゃんと文字として扱える
# Ruby 1.8.7
"文字".size #=> 6
"文字".bytesize #=> 6
"文字"[0] #=> 230 (0xE6)
"文字".reverse #=> "??????"
# Ruby 1.9.3
"文字".size #=> 2
"文字".bytesize #=> 6
"文字"[0] #=> "文"
"文字".reverse #=> "字文"
14/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
16. String#encoding
文字列のエンコーディングを調べる
"あ".encoding #=> #<Encoding:UTF-8>
15/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
17. String#encode
エンコーディング変換
str = "あ"
str.encoding #=> #<Encoding:UTF-8>
str2 = str.encode("cp932")
str2.encoding #=> #<Encoding:Windows-31J>
16/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
18. エンコーディングは何で決まる?
✓ スクリプトエンコーディング
✓ 外部エンコーディング
✓ 内部エンコーディング
17/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
19. スクリプトエンコーディング
✓ スクリプト中の文字列リテラルのエンコーディ
ングを決定する
✓ スクリプト先頭行のマジックコメントで指定する
# coding: utf-8
"あ".encoding #=> #<Encoding:UTF-8>
✓ デフォルトは US-ASCII (または -K で指定)
18/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
20. スクリプトエンコーディング
✓ US-ASCII で範囲外の "xHH" 表記を含む場
合は ASCII-8BIT
✓ "uXXXX" 表記を含む場合は UTF-8
# coding: us-ascii
"a".encoding #=> #<Encoding:US-ASCII>
"x41".encoding #=> #<Encoding:US-ASCII>
"xFF".encoding #=> #<Encoding:ASCII-8BIT>
"u3042".encoding #=> #<Encoding:UTF-8>
19/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
21. 外部エンコーディング
✓ ファイル内の文字列が何のエンコーディングか
を指定する
✓ File.open 時に指定する
f = File.open("file.txt", "r:utf-8")
f.gets # UTF-8文字列
✓ ファイルの内容は UTF-8
✓ 読み込んだ文字列も UTF-8 エンコーディング
20/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
22. 外部エンコーディング(書き込み)
f = File.open("file.txt", "w:utf-8")
f.puts("ほげ")
✓ 文字列が UTF-8 に変換されて書き込まれる
21/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
23. 内部エンコーディング
✓ ファイルから読み込んだ文字列のエンコーディ
ングを変換する
✓ File.open 時に指定する
File.open("file.txt", "r:cp932:utf-8")
✓ ファイルの内容は CP932
✓ 読み込んだ文字列は UTF-8 エンコーディング
✓ 書き込み時はあまり関係ない
22/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
24. もうちょっ
と詳しく 23/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
25. 読み込み時の変換
✓ メソッドによって変換したりしなかったり
✓ バイナリ読み込みメソッド(常に ASCII-8BIT)
✓ read(n) / read_nonblock / readpartial /
sysread
✓ テキスト読み込みメソッド
✓ foreach / readlines / each_line / lines /
gets / getc / ungetc / read / readchar /
readline / readlines
24/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
26. 外部エンコーディング未指定時
読み込み時は Encoding.default_external が使わ
れる
Encoding.default_external #=> #<Encoding:UTF-8>
File.open("file.txt", "r:cp932").gets.encoding
#=> #<Encoding:Windows-31J>
File.open("file.txt", "r").gets.encoding
#=> #<Encoding:UTF-8>
25/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
27. Encoding.default_external
✓ -E オプション / ロケール
% ruby -Eutf-8 -e 'p Encoding.default_external'
#<Encoding:UTF-8>
% LC_ALL=C ruby -e 'p Encoding.default_external'
#<Encoding:US-ASCII>
% LC_ALL=ja_JP.UTF-8 ruby -e 'p Encoding.default_external'
#<Encoding:UTF-8>
✓ かならず値がある
✓ 外部エンコーディングのデフォルトじゃない
26/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
28. 書き込み時の変換
✓ メソッドには依らない
✓ IO に外部エンコーディングが指定されていた
場合は変換される
✓ 外部エンコーディングが ASCII-8BIT の場合
は変換されない
✓ 外部エンコーディングが指定されていない場
合は変換されない(基本的には)
27/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
29. 正規表現
のエンコー
ディング
Rubyのエンコーディング - NSEG#30
28/45
Powered by Rabbit 1.0.9
30. 正規表現リテラル
✓ ASCII文字のみの場合は US-ASCII
✓ 非ASCII文字はスクリプトエンコーディング
# coding: utf-8
/あ/.encoding #=> #<Encoding:UTF-8>
/./.encoding #=> #<Encoding:US-ASCII>
/./n.encoding #=> #<Encoding:US-ASCII>
/./s.encoding #=> #<Encoding:Windows-31J>
/./e.encoding #=> #<Encoding:EUC-JP>
/./u.encoding #=> #<Encoding:UTF-8>
29/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
31. 正規表現リテラル
✓ US-ASCII で範囲外の "xHH" 表記を含む場
合は ASCII-8BIT
✓ "uXXXX" 表記を含む場合は UTF-8
# coding: us-ascii
/a/.encoding #=> #<Encoding:US-ASCII>
/x41/.encoding #=> #<Encoding:US-ASCII>
/xFF/.encoding #=> #<Encoding:ASCII-8BIT>
/u3042/.encoding #=> #<Encoding:UTF-8>
30/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
32. はまり
どころ
Rubyのエンコーディング - NSEG#30
31/45
Powered by Rabbit 1.0.9
33. 文字列比較
文字が等しくてもエンコーディングが異なれば異なる
u = "あ".encode("utf-8")
s = "あ".encode("cp932")
u == s #=> false
32/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
34. 文字列比較
バイト列が等しくてもエンコーディングが異なれば異
なる
# coding: utf-8
u = "あ"
b = "あ".force_encoding("ascii-8bit")
u == b #=> false
33/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
35. 文字列比較
エンコーディングが異なっていてもASCII互換のエン
コーディングでASCII文字だけなら比較できる
# coding: utf-8
u = "abc".encode("utf-8")
s = "abc".encode("cp932")
u == s #=> true
34/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
36. 正規表現
エンコーディングが異なっていたらエラー
# coding: utf-8
"あ" =~ /./s
# incompatible encoding regexp match (Windows-31J regexp
# with UTF-8 string) (Encoding::CompatibilityError)
35/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
37. 正規表現
ASCII文字だけならエラーにならない
# coding: utf-8
"ABC" =~ /./s
ASCII文字だけでテストしたりすると本番で落ちたり
36/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
38. 文字列結合
異なるエンコーディング同士の結合はエラー
u = "あ".encode("utf-8")
s = "あ".encode("cp932")
u + s
# incompatible character encodings: UTF-8 and Windows-31J
# (Encoding::CompatibilityError)
37/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
39. 文字列結合
ASCII文字だけならエラーにならない
u = "ABC".encode("utf-8")
s = "DEF".encode("cp932")
u + s #=> "ABCDEF" (UTF-8)
38/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
40. リテラル
スクリプトエンコーディングに合わない文字があると
スクリプトのロード時にエラー
# coding: cp932
"あ" # UTF-8の「あ」
# invalid multibyte char (Windows-31J)
39/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
41. リテラル
でも "xHH" 表記だとエラーにならない
# coding: cp932
"xE3x81x82" # UTF-8の「あ」
40/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
42. 不正な文字
正規表現との比較でエラー
# coding: cp932
str = "xE3x81x82" # ここではエラーにならない
str =~ /./
# invalid byte sequence in Windows-31J (ArgumentError)
41/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
43. 不正な文字
エンコーディングがあってたとしても不正な文字は発
生しうる
# 不正な文字が入っているファイルをUTF-8指定で読んでしまった
File.open("utf-8.txt", "r:utf-8").gets # エラーにはならない
UTF-8 エンコーディングの文字列が得られるが、不
正な文字が含まれているかもしれない
42/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
44. 変換
内部エンコーディングを指定すると不正な文字で変
換エラー
# CP932だけど不正な文字が入ってる
f = File.open("cp932.txt", "r:cp932:utf-8")
f.gets # 不正な文字が含まれる行でエラー
# `gets': "xFCxA1" from Windows-31J to UTF-8
# (Encoding::UndefinedConversionError)
43/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
45. 変換
✓ 外部エンコーディングを指定してないと環境変
数の影響うけるかも
✓ 内部エンコーディング指定すると自動的に変
換されるけど、読むだけでエラーになるかも
44/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
46. まとめ
✓ 文字単位の処理は便利
✓ ハマる時はハマる
✓ データのエンコーディングを統一するのが吉
45/45
Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9