rabbit-slide-tommy-rubyencoding 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ RubyEncoding.rab
data/6752.png ADDED
Binary file
data/README.rd ADDED
@@ -0,0 +1,24 @@
1
+ = 本当はこわいエンコーディングの話
2
+
3
+ 東京Ruby会議10 #tkrk10 で発表したスライド
4
+
5
+ == 作者向け
6
+
7
+ === 表示
8
+
9
+ rake
10
+
11
+ === 公開
12
+
13
+ rake publish
14
+
15
+ == 閲覧者向け
16
+
17
+ === インストール
18
+
19
+ gem install rabbit-slide-tommy-rubyencoding
20
+
21
+ === 表示
22
+
23
+ rabbit rabbit-slide-tommy-rubyencoding.gem
24
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ Rabbit::Task::Slide.new do |task|
6
+ # task.spec.licenses = ["CC BY-SA 3.0"]
7
+ # task.spec.files += Dir.glob("doc/**/*.*")
8
+ # task.spec.files -= Dir.glob("private/**/*.*")
9
+ # task.spec.add_runtime_dependency("YOUR THEME")
10
+ end
data/RubyEncoding.rab ADDED
@@ -0,0 +1,485 @@
1
+ = 本当は((*こわい*))\nエンコーディングの話
2
+
3
+ # : subtitle
4
+ # サブタイトル
5
+ : author
6
+ とみたまさひろ
7
+ # : institution
8
+ # 所属
9
+ : content-source
10
+ 東京Ruby会議10
11
+ : date
12
+ 2013-01-13
13
+ : allotted-time
14
+ 15m
15
+ : theme
16
+ clear-blue+
17
+
18
+ = 自己紹介
19
+
20
+ # image
21
+ # src = icon.jpg
22
+ # relative-height = 20
23
+ # align = right
24
+ # relative-margin-top = -30
25
+ # relative-margin-right = -10
26
+
27
+ * とみた まさひろ
28
+ * http://((*tmtms*)).hatenablog.com
29
+ * https://twitter.com/((*tmtms*))
30
+ * 好きなもの/環境
31
+ * ((*Ruby*)), Rabbit, MySQL, Emacs, Git, Ubuntu, ThinkPad
32
+ * 所属など
33
+ * 長野県北部在住 / 某社プログラマー / 日本MySQLユーザ会 / 長野ソフトウェア技術者グループ(NSEG)
34
+
35
+ = エンコーディング
36
+
37
+ = エンコーディングとは
38
+
39
+ * 文字符号化方式
40
+ * 文字をどのようなバイト列で表現するか
41
+ * UTF-8 とか EUC-JP とか SHIFT_JIS とかそーゆー奴
42
+ * 「charset」とか呼ばれたりする
43
+ * 「文字コード」とか呼ばれたりする
44
+
45
+ = 同じバイト列でも別の文字
46
+
47
+ ((*0xC2 0xA9*)) の2バイトは
48
+
49
+ * UTF-8 では「((*©*))」1文字
50
+ * EUC-JP では「((*息*))」1文字
51
+ * SHIFT_JIS では「((*ツゥ*))」2文字
52
+
53
+ = Ruby 1.8
54
+
55
+ * ((*"\xC2\xA9"*)) という文字列は Ruby 的にはただのバイト列
56
+ * エンコーディング情報を持たない
57
+ * "((*©*))"(UTF-8) として扱うか "((*息*))"(EUC-JP) として扱うかはプログラム次第
58
+ * 正規表現にはエンコーディングあり
59
+ * /〜/n /〜/s /〜/u /〜/e
60
+
61
+ = Ruby 1.9
62
+
63
+ * 文字列のエンコーディングは文字列自身が知っている
64
+ * "((*©*))"(UTF-8) と "((*息*))"(EUC-JP) は同じバイト列だけど異なる文字列
65
+ * "((*あ*))"(UTF-8) と "((*あ*))"(EUC-JP) は同じ文字を表してるけど等しくない
66
+ * 同じプログラム中で複数のエンコーディングの文字列を同時に扱える(珍しいかも)
67
+ * 正規表現にもエンコーディングあり
68
+
69
+ = エンコーディング一覧(('tag:small:(1.9.3)'))
70
+
71
+ (('tag:center'))Ruby 自身が持ってるので環境に依存しない
72
+
73
+ ASCII-8BIT Big5 Big5-HKSCS Big5-UAO CP50220 CP50221 CP51932 CP850
74
+ CP852 CP855 CP949 CP950 CP951 EUC-JP EUC-KR EUC-TW Emacs-Mule
75
+ GB12345 GB18030 GB1988 GB2312 GBK IBM437 IBM737 IBM775 IBM852
76
+ IBM855 IBM857 IBM860 IBM861 IBM862 IBM863 IBM864 IBM865 IBM866
77
+ IBM869 ISO-2022-JP ISO-2022-JP-2 ISO-2022-JP-KDDI ISO-8859-1
78
+ ISO-8859-10 ISO-8859-11 ISO-8859-13 ISO-8859-14 ISO-8859-15
79
+ ISO-8859-16 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-6
80
+ ISO-8859-7 ISO-8859-8 ISO-8859-9 KOI8-R KOI8-U MacJapanese
81
+ SJIS-DoCoMo SJIS-KDDI SJIS-SoftBank Shift_JIS TIS-620 US-ASCII
82
+ UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE UTF-7 UTF-8
83
+ UTF8-DoCoMo UTF8-KDDI UTF8-MAC UTF8-SoftBank Windows-1250
84
+ Windows-1251 Windows-1252 Windows-1253 Windows-1254 Windows-1255
85
+ Windows-1256 Windows-1257 Windows-1258 Windows-31J Windows-874
86
+ eucJP-ms macCentEuro macCroatian macCyrillic macGreek macIceland
87
+ macRoman macRomania macThai macTurkish macUkraine
88
+ stateless-ISO-2022-JP stateless-ISO-2022-JP-KDDI
89
+
90
+ = うれしいこと
91
+
92
+ = 1.8では((*バイト*))単位
93
+
94
+ # coderay ruby
95
+
96
+ "あいう".size #=> 9
97
+ "あいう".bytesize #=> 9
98
+
99
+ "あいう".chars{|c| ... }
100
+ #=> "\xE3","\x81","\x82", ...
101
+
102
+ "あいう"[0] #=> 0xE3
103
+ "あいう".reverse
104
+ #=> "\x86\x81\xE3\x84\x81\xE3\x82\x81\xE3"
105
+
106
+ = 1.9では((*文字*))単位
107
+
108
+ # coderay ruby
109
+
110
+ "あいう".size #=> 3
111
+ "あいう".bytesize #=> 9
112
+
113
+ "あいう".chars{|c| ... }
114
+ #=> "あ", "い", "う"
115
+
116
+ "あいう"[0] #=> "あ"
117
+ "あいう".reverse #=> "ういあ"
118
+
119
+ = エンコーディング変換
120
+
121
+ # coderay ruby
122
+
123
+ # -*- coding: utf-8 -*-
124
+ s = "あいう"
125
+ #=> "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86"
126
+ s.encoding #=> #<Encoding:UTF-8>
127
+
128
+ s2 = s.encode("CP932")
129
+ #=> "\x82\xA0\x82\xA2\x82\xA4"
130
+ s2.encoding #=> #<Encoding:Windows-31J>
131
+
132
+ = IOで変換してくれる
133
+
134
+ # coderay ruby
135
+
136
+ File.open("cp932.txt", "r:CP932").read
137
+ #=> CP932 文字列
138
+
139
+ File.open("cp932.txt", "r:CP932:UTF-8").read
140
+ #=> UTF-8 文字列
141
+
142
+ File.open("cp932.txt").read
143
+ #=> 環境依存
144
+
145
+ = うれしいことばかりじゃない
146
+
147
+ = 変換((*先*))にない文字
148
+
149
+ # coderay ruby
150
+
151
+ # -*- coding: utf-8 -*-
152
+ "あ♥".encode("CP932")
153
+ #=> Encoding::UndefinedConversionError
154
+
155
+ = 変換((*元*))にない文字
156
+
157
+ # coderay ruby
158
+
159
+ # -*- coding: utf-8 -*-
160
+ "あ\xFF".encode("CP932")
161
+ #=> Encoding::InvalidByteSequenceError
162
+
163
+ = エンコーディングがあっても\n変換できるとは限らない
164
+
165
+ # coderay ruby
166
+
167
+ # -*- coding: utf-8 -*-
168
+ "あいう".encode("UTF-7")
169
+ #=> Encoding::ConverterNotFoundError
170
+
171
+ = エンコーディングの((*不一致*))
172
+
173
+ # coderay ruby
174
+
175
+ utf8 = "あいう"
176
+ cp932 = "あ".encode("CP932")
177
+ utf8.start_with?(cp932)
178
+ #=> Encoding::CompatibilityError
179
+
180
+ = 文字列と正規表現の\nエンコーディングの((*不一致*))
181
+
182
+ # coderay ruby
183
+
184
+ utf8 = "あいう"
185
+ re = /./s
186
+ utf8 =~ re
187
+ #=> Encoding::CompatibilityError
188
+
189
+ = エンコーディングが同じでも\n((*不正*))な文字を含んでいる
190
+
191
+ # coderay ruby
192
+
193
+ utf8 = "あ\xFF"
194
+ utf8 =~ /./
195
+ #=> invalid byte sequence in UTF-8
196
+ # (ArgumentError)
197
+
198
+ = IO
199
+
200
+ = メソッドによって\nエンコーディングが異なる
201
+
202
+ * テキスト読み込み(エンコードあり)
203
+ * IO#gets
204
+ * IO#getc
205
+ * IO#lines
206
+ * IO#read 等
207
+
208
+ * バイナリ読み込み(ASCII-8BIT固定)
209
+ * IO#read(n)
210
+ * IO#sysread 等
211
+
212
+ = IO#read
213
+
214
+ * IO#read(size) は ((*ASCII-8BIT*))
215
+ * IO#read() は((*外部エンコーディング*))依存
216
+ * 引数の有無によって結果のエンコーディングが異なる!
217
+ * なにそれ((*こわい*))
218
+
219
+ = 外部エンコーディング
220
+
221
+ * ファイル自身は自分の内容のエンコーディングを((*知らない*))
222
+ * ファイルから読み込んだ文字列の Ruby 内でのエンコーディングは何らかの方法で指定する必要がある
223
+
224
+ = 引数で指定
225
+
226
+ # coderay ruby
227
+
228
+ File.open(filename, "r:UTF-8")
229
+
230
+ File.read(filename, :encoding=>"UTF-8")
231
+
232
+ = 環境変数
233
+
234
+ 引数で指定されてない場合は環境変数が参照される
235
+
236
+ * LC_ALL
237
+ * LC_CTYPE
238
+ * LANG
239
+
240
+ = 環境変数による違い
241
+
242
+ # coderay text
243
+
244
+ % cat utf-8.txt
245
+ あいうえお
246
+ % export LC_ALL=C
247
+ % ruby -e 'p File.read("utf-8.txt").size'
248
+ 16
249
+ % export LC_ALL=ja_JP.UTF-8
250
+ % ruby -e 'p File.read("utf-8.txt").size'
251
+ 6
252
+
253
+ (('tag:center'))環境変数によって動きが変わっちゃう!((*こわい*))
254
+
255
+ = 入力時にはエラーにならない
256
+
257
+ # coderay ruby
258
+
259
+ utf8 = File.read("utf8.txt", :encoding=>"UTF-8")
260
+ # 実は UTF-8 として不正な文字が含まれていて
261
+
262
+ 〜〜〜〜〜〜
263
+
264
+ # ずっと後で別のメソッドでエラーになったり
265
+ utf8 =~ /./
266
+ #=> invalid byte sequence in UTF-8 (ArgumentError)
267
+
268
+ = CGI
269
+
270
+ # coderay ruby
271
+
272
+ require "cgi"
273
+ cgi = CGI.new
274
+
275
+ 不正な文字のパラメータを渡すとエラー
276
+
277
+ GET http://example.com/hoge.cgi?fuga=%FF
278
+
279
+ #=> Accept-Charset encoding error (CGI::InvalidEncoding)
280
+
281
+ = Rails
282
+
283
+ 不正な文字のパラメータを渡すとエラー
284
+
285
+ POST http://example.com/posts
286
+
287
+ post[title]=%FF
288
+
289
+ #=> ArgumentError (invalid byte sequence in UTF-8)
290
+
291
+ = エラーになりすぎ((*こわい*))!
292
+
293
+ = 対処
294
+
295
+ = 変換((*先*))にない文字を置換
296
+
297
+ # coderay ruby
298
+
299
+ "あ♥".encode("CP932")
300
+ #=> Encoding::UndefinedConversionError
301
+
302
+ "あ♥".encode("CP932", :undef=>:replace)
303
+ #=> "あ?"
304
+
305
+ = 変換((*元*))にない文字を置換
306
+
307
+ # coderay ruby
308
+
309
+ "あ\xFF".encode("CP932")
310
+ #=> Encoding::InvalidByteSequenceError
311
+
312
+ "あ\xFF".encode("CP932", :invalid=>:replace)
313
+ #=> "あ?"
314
+
315
+ = 置換文字の指定
316
+
317
+ # coderay ruby
318
+
319
+ "あ♥".encode("CP932", :undef=>:replace, :replace=>"〓")
320
+ #=> CP932 で "あ〓"
321
+
322
+ = そもそも変換が必要になるようなことをしないのが((*吉*))
323
+
324
+ = UTF-8に((*統一*))すれば\nたいていは問題ない
325
+
326
+ = UTF-8に統一したつもりでも\n他のエンコーディングが現れることも
327
+
328
+ # coderay ruby
329
+
330
+ File.open(filename, "r:UTF-8").read
331
+ #=> UTF-8 文字列
332
+
333
+ File.open(filename).read
334
+ #=> 環境依存
335
+
336
+ = いちいち引数で指定する?
337
+
338
+ = デフォルト値を指定する
339
+
340
+ プログラムで使用するファイルのエンコーディングがすべて同一であれば
341
+
342
+ # coderay ruby
343
+
344
+ Encoding.default_external = "UTF-8"
345
+
346
+ File.read(filename) #=> UTF-8文字列
347
+
348
+ = これで問題ない?
349
+
350
+ = ASCII-8BIT
351
+
352
+ = メソッドによっては ASCII-8BIT
353
+
354
+ # coderay ruby
355
+
356
+ f = File.open(filename, "r:UTF-8")
357
+ f.gets #=> UTF-8
358
+ f.read(10) #=> ASCII-8BIT
359
+
360
+ = ソケットは ASCII-8BIT
361
+
362
+ # coderay ruby
363
+
364
+ require 'socket'
365
+ Encoding.default_external = "UTF-8"
366
+ TCPSocket.new('127.0.0.1', 25).gets
367
+ #=> ASCII-8BIT
368
+
369
+ = ((*気をつける*))しかない
370
+
371
+ = ((*不正*))な文字
372
+
373
+ = エンコーディングがUTF-8でも\nデータがUTF-8とは限らない
374
+
375
+ # coderay ruby
376
+
377
+ f = File.open("/dev/urandom", "r:UTF-8")
378
+ str = f.gets
379
+ str.encoding #=> #<Encoding:UTF-8>
380
+ str =~ /./
381
+ #=> invalid byte sequence in UTF-8 (ArgumentError)
382
+
383
+ = 事前に判定
384
+
385
+ String#valid_encoding?
386
+
387
+ # coderay ruby
388
+
389
+ f = File.open("/dev/urandom", "r:UTF-8")
390
+ str = f.gets
391
+ str.valid_encoding? #=> false
392
+
393
+ = 不正な文字を((*置換したい*))
394
+
395
+ * 簡単な方法は((*ない*))
396
+
397
+ * String#encode は変換元と変換先が同じ場合は((*何もしない*))
398
+
399
+ # coderay ruby
400
+
401
+ # -*- coding: utf-8 -*-
402
+ "あ\xFF".encode("CP932", :invalid=>:replace)
403
+ #=> "あ?"
404
+ "あ\xFF".encode("UTF-8", :invalid=>:replace)
405
+ #=> "あ\xFF"
406
+
407
+ = Iconv ではできたけど…
408
+
409
+ # coderay ruby
410
+
411
+ require "iconv"
412
+ src = "あい\xFFうえ"
413
+ dst = ""
414
+ iconv = Iconv.new("utf-8", "utf-8")
415
+ begin
416
+ dst.concat iconv.iconv(src)
417
+ rescue Iconv::IllegalSequence => e
418
+ dst.concat e.success
419
+ dst.concat "〓"
420
+ src = e.failed[1..-1]
421
+ retry
422
+ end
423
+ dst #=> "あい〓うえ"
424
+
425
+ (('tag:center'))((*Iconv は 2.0 で廃止*))
426
+
427
+ = 同じ文字群を持つ\n別のエンコーディングを経由
428
+
429
+ # coderay ruby
430
+
431
+ "あ\xFF".
432
+ encode("UTF-16", :invalid=>:replace).
433
+ encode("UTF-8")
434
+ #=> "あ�"
435
+
436
+ = 2.0.xだとできるようになる?
437
+
438
+ # image
439
+ # src = 6752.png
440
+ # relative-height = 100
441
+
442
+ = CGI や Rails
443
+
444
+ = パラメータが不正な文字で\nエラー
445
+
446
+ * 放置でいいんじゃない?
447
+ * 外部からの不正なデータは最前線でエラーになってくれた方がありがたかったり
448
+ * 後の処理に渡されても扱いに困るだけ
449
+ * 実害はログが鬱陶しいくらい?
450
+
451
+ = CGIで頑張るなら
452
+
453
+ # coderay ruby
454
+
455
+ require 'cgi'
456
+ # 一旦 ASCII-8BIT で受けて
457
+ cgi = CGI.new :accept_charset=>"ASCII-8BIT"
458
+ # パラメータ毎にどうにかする
459
+ hoge = cgi['hoge'].encode("UTF-8", "UTF-8")
460
+ unless hoge.valid_encoding?
461
+ ...
462
+
463
+ = Railsは...
464
+
465
+ (('tag:center'))よくわかりません (><)
466
+
467
+ = おまけ
468
+
469
+ = ASCII文字だけなら\n異なるエンコーディングでも\nエラーにならない
470
+
471
+ # coderay ruby
472
+
473
+ # -*- coding: utf-8 -*-
474
+ "あ" =~ /./s #=> Encoding::CompatibilityError
475
+ "ABC" =~ /./s #=> エラーにならない
476
+
477
+ ASCII文字だけでテストしてると本番でエラーになったり((*こわい*))
478
+
479
+ = まとめ
480
+
481
+ * 内部のエンコーディングは UTF-8 に統一しよう
482
+ * IO 読み込みで ASCII-8BIT になってることがある
483
+ * 外部からのデータは不正な文字が入ってることがある
484
+
485
+ (('tag:center'))((*ちゃんと気をつければ(('tag:x-small:そんなに'))こわくない*))
data/blog.png ADDED
Binary file
data/config.yaml ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ id: rubyencoding
3
+ base_name: RubyEncoding
4
+ tags: []
5
+ presentation_date:
6
+ version: 1.0.0
7
+ licenses: []
8
+ slideshare_id:
9
+ speaker_deck_id:
10
+ author:
11
+ markup_language: :rd
12
+ name: TOMITA Masahiro
13
+ email: tommy@tmtm.org
14
+ rubygems_user: tommy
15
+ slideshare_user: tmtm
16
+ speaker_deck_user:
data/icon.jpg ADDED
Binary file
data/icon2.jpg ADDED
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-tommy-rubyencoding
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - TOMITA Masahiro
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rabbit
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.2
30
+ description: ! '東京Ruby会議10 #tkrk10 で発表したスライド'
31
+ email:
32
+ - tommy@tmtm.org
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .rabbit
38
+ - config.yaml
39
+ - Rakefile
40
+ - README.rd
41
+ - 6752.png
42
+ - blog.png
43
+ - icon2.jpg
44
+ - icon.jpg
45
+ - RubyEncoding.rab
46
+ - pdf/rubyencoding-RubyEncoding.pdf
47
+ homepage: http://slide.rabbit-shocker.org/authors/tommy/rubyencoding/
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.23
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: 本当はこわいエンコーディングの話
71
+ test_files: []