• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rubyのエンコーディング
 

Rubyのエンコーディング

on

  • 10,752 views

 

Statistics

Views

Total Views
10,752
Views on SlideShare
6,683
Embed Views
4,069

Actions

Likes
14
Downloads
18
Comments
0

9 Embeds 4,069

http://tmtms.hatenablog.com 3000
http://d.hatena.ne.jp 944
https://twitter.com 93
http://webcache.googleusercontent.com 14
http://s.deeeki.com 7
https://si0.twimg.com 3
http://www.hanrss.com 3
http://cache.yahoofs.jp 3
https://twimg0-a.akamaihd.net 2
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rubyのエンコーディング Rubyのエンコーディング Presentation Transcript

    • Rubyのエンコーディング NSEG#30 とみたまさひろ 2012-08-25Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 自己紹介 ✓ とみた まさひろ (ペンネーム) ✓ プログラマー (Ruby & C) ✓ http://d.hatena.ne.jp/tmtms ✓ http://twitter.com/tmtms ✓ 好きなもの ✓ Ruby, MySQL, Ubuntu, Emacs, Git 1/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 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
    • Ruby 1.8 は オワコンRubyのエンコーディング - NSEG#30 3/45 Powered by Rabbit 1.0.9
    • 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • Ruby 1.9 を使いまし ょうRubyのエンコーディング - NSEG#30 5/45 Powered by Rabbit 1.0.9
    • 1.9の 特徴Rubyのエンコーディング - NSEG#30 6/45 Powered by Rabbit 1.0.9
    • 一番大きい のはエンコ ーディングRubyのエンコーディング - NSEG#30 7/45 Powered by Rabbit 1.0.9
    • Rubyのエンコーディング http://d.hatena.ne.jp/tmtms/20120812/ruby_encoding 8/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • エンコーディング? ✓ 文字符号化方式 ✓ UTF-8 とか EUC-JP とか SHIFT_JIS とか そーゆー奴 ✓ charset とか呼ばれたり ✓ いわゆる「文字コード」 9/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 同じ文字でも異なるコード 「あ」 ✓ UTF-8 では 0xE3 0x81 0x82 の3バイト ✓ EUC-JP では 0xA4 0xA2 の2バイト ✓ SHIFT_JIS では 0x82 0xA0 の2バイト 10/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 同じバイト列でも別の文字 0xC2 0xA9 の2バイトは ✓ UTF-8 では「©」1文字 ✓ EUC-JP では「息」1文字 ✓ SHIFT_JIS では「ツゥ」2文字 11/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • Ruby 1.8.x ✓ "xC2xA9" という文字列は Ruby 的にはた だのバイト列 ✓ エンコーディング情報を持たない ✓ "©"(UTF-8) として扱うか "息"(EUC-JP) とし て扱うかはプログラム次第 12/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • Ruby 1.9.x ✓ 文字列のエンコーディングは文字列自身が知 っている ✓ "©"(UTF-8) と "息"(EUC-JP) は同じバイト列 だけど異なる文字列 ✓ "あ"(UTF-8) と "あ"(EUC-JP) は同じ文字を表 してるけど等しくない ✓ 同じプログラム中で複数のエンコーディングの 文字列を同時に扱える(珍しいかも) 13/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • ちゃんと文字として扱える # Ruby 1.8.7 "文字".size #=> 6 "文字".bytesize #=> 6 "文字"[0] #=> 230 (0xE6) "文字".reverse #=> "??????" # Ruby 1.9.3 "文字".size #=> 2 "文字".bytesize #=> 6 "文字"[0] #=> "文" "文字".reverse #=> "字文" 14/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • String#encoding 文字列のエンコーディングを調べる "あ".encoding #=> #<Encoding:UTF-8> 15/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • String#encode エンコーディング変換 str = "あ" str.encoding #=> #<Encoding:UTF-8> str2 = str.encode("cp932") str2.encoding #=> #<Encoding:Windows-31J> 16/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • エンコーディングは何で決まる? ✓ スクリプトエンコーディング ✓ 外部エンコーディング ✓ 内部エンコーディング 17/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • スクリプトエンコーディング ✓ スクリプト中の文字列リテラルのエンコーディ ングを決定する ✓ スクリプト先頭行のマジックコメントで指定する # coding: utf-8 "あ".encoding #=> #<Encoding:UTF-8> ✓ デフォルトは US-ASCII (または -K で指定) 18/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • スクリプトエンコーディング ✓ 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 外部エンコーディング ✓ ファイル内の文字列が何のエンコーディングか を指定する ✓ File.open 時に指定する f = File.open("file.txt", "r:utf-8") f.gets # UTF-8文字列 ✓ ファイルの内容は UTF-8 ✓ 読み込んだ文字列も UTF-8 エンコーディング 20/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 外部エンコーディング(書き込み) f = File.open("file.txt", "w:utf-8") f.puts("ほげ") ✓ 文字列が UTF-8 に変換されて書き込まれる 21/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 内部エンコーディング ✓ ファイルから読み込んだ文字列のエンコーディ ングを変換する ✓ File.open 時に指定する File.open("file.txt", "r:cp932:utf-8") ✓ ファイルの内容は CP932 ✓ 読み込んだ文字列は UTF-8 エンコーディング ✓ 書き込み時はあまり関係ない 22/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • もうちょっ と詳しく 23/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 読み込み時の変換 ✓ メソッドによって変換したりしなかったり ✓ バイナリ読み込みメソッド(常に ASCII-8BIT) ✓ read(n) / read_nonblock / readpartial / sysread ✓ テキスト読み込みメソッド ✓ foreach / readlines / each_line / lines / gets / getc / ungetc / read / readchar / readline / readlines 24/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 外部エンコーディング未指定時 読み込み時は 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 書き込み時の変換 ✓ メソッドには依らない ✓ IO に外部エンコーディングが指定されていた 場合は変換される ✓ 外部エンコーディングが ASCII-8BIT の場合 は変換されない ✓ 外部エンコーディングが指定されていない場 合は変換されない(基本的には) 27/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 正規表現 のエンコー ディングRubyのエンコーディング - NSEG#30 28/45 Powered by Rabbit 1.0.9
    • 正規表現リテラル ✓ 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 正規表現リテラル ✓ 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/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • はまり どころRubyのエンコーディング - NSEG#30 31/45 Powered by Rabbit 1.0.9
    • 文字列比較 文字が等しくてもエンコーディングが異なれば異なる u = "あ".encode("utf-8") s = "あ".encode("cp932") u == s #=> false 32/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 文字列比較 バイト列が等しくてもエンコーディングが異なれば異 なる # coding: utf-8 u = "あ" b = "あ".force_encoding("ascii-8bit") u == b #=> false 33/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 文字列比較 エンコーディングが異なっていてもASCII互換のエン コーディングでASCII文字だけなら比較できる # coding: utf-8 u = "abc".encode("utf-8") s = "abc".encode("cp932") u == s #=> true 34/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 正規表現 エンコーディングが異なっていたらエラー # coding: utf-8 "あ" =~ /./s # incompatible encoding regexp match (Windows-31J regexp # with UTF-8 string) (Encoding::CompatibilityError) 35/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 正規表現 ASCII文字だけならエラーにならない # coding: utf-8 "ABC" =~ /./s ASCII文字だけでテストしたりすると本番で落ちたり 36/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 文字列結合 異なるエンコーディング同士の結合はエラー u = "あ".encode("utf-8") s = "あ".encode("cp932") u + s # incompatible character encodings: UTF-8 and Windows-31J # (Encoding::CompatibilityError) 37/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 文字列結合 ASCII文字だけならエラーにならない u = "ABC".encode("utf-8") s = "DEF".encode("cp932") u + s #=> "ABCDEF" (UTF-8) 38/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • リテラル スクリプトエンコーディングに合わない文字があると スクリプトのロード時にエラー # coding: cp932 "あ" # UTF-8の「あ」 # invalid multibyte char (Windows-31J) 39/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • リテラル でも "xHH" 表記だとエラーにならない # coding: cp932 "xE3x81x82" # UTF-8の「あ」 40/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 不正な文字 正規表現との比較でエラー # coding: cp932 str = "xE3x81x82" # ここではエラーにならない str =~ /./ # invalid byte sequence in Windows-31J (ArgumentError) 41/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 不正な文字 エンコーディングがあってたとしても不正な文字は発 生しうる # 不正な文字が入っているファイルをUTF-8指定で読んでしまった File.open("utf-8.txt", "r:utf-8").gets # エラーにはならない UTF-8 エンコーディングの文字列が得られるが、不 正な文字が含まれているかもしれない 42/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 変換 内部エンコーディングを指定すると不正な文字で変 換エラー # CP932だけど不正な文字が入ってる f = File.open("cp932.txt", "r:cp932:utf-8") f.gets # 不正な文字が含まれる行でエラー # `gets: "xFCxA1" from Windows-31J to UTF-8 # (Encoding::UndefinedConversionError) 43/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • 変換 ✓ 外部エンコーディングを指定してないと環境変 数の影響うけるかも ✓ 内部エンコーディング指定すると自動的に変 換されるけど、読むだけでエラーになるかも 44/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9
    • まとめ ✓ 文字単位の処理は便利 ✓ ハマる時はハマる ✓ データのエンコーディングを統一するのが吉 45/45Rubyのエンコーディング - NSEG#30 Powered by Rabbit 1.0.9