rabbit-slide-tommy-rubyencoding 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []