rabbit-slide-kou-rubykaigi-2018 2018.6.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1668 @@
1
+ = My way with Ruby
2
+
3
+ : author
4
+ Kouhei Sutou
5
+ : institution
6
+ ClearCode Inc.
7
+ : content-source
8
+ RubyKaigi 2018
9
+ : date
10
+ 2018-06-01
11
+ : start-time
12
+ 2018-06-01T09:40:00+09:00
13
+ : end-time
14
+ 2018-06-01T10:35:00+09:00
15
+ : theme
16
+ .
17
+
18
+ = Ad: Silver sponsor
19
+
20
+ # img
21
+ # src = images/clear-code-rubykaigi-2018-silver-sponsor.png
22
+ # relative_height = 100
23
+ # reflect_ratio = 0.1
24
+
25
+ == Slide properties
26
+
27
+ : enable-title-on-image
28
+ false
29
+
30
+ = Keynote-ish topic\n(('note:キーノートっぽい話題'))
31
+
32
+ Did you think about it?\n
33
+ (('note:考えたことある?'))
34
+
35
+ = Keynote-ish topic1\n(('note:キーノートっぽい話題1'))
36
+
37
+ Future\n
38
+ (('note:未来のこと'))
39
+
40
+ = Keynote-ish topic2\n(('note:キーノートっぽい話題2'))
41
+
42
+ Focus on\n
43
+ one thing\n
44
+ ((*deeply*))\n
45
+ (('note:なにかを深掘り'))
46
+
47
+ = Keynote-ish topic3\n(('note:キーノートっぽい話題3'))
48
+
49
+ Overview\n
50
+ (('note:俯瞰した話'))
51
+
52
+ = My activities\nas a Rubyist\n(('note:私のRubyist活動'))
53
+
54
+ * Increase what Ruby can\n
55
+ (('note:Rubyでできることを増やす'))
56
+ * Maintain libraries\n
57
+ (('note:ライブラリーのメンテナンス'))
58
+
59
+ = The number of developing libraries\n(('note:開発しているライブラリー数'))
60
+
61
+ About 130\n
62
+ (('note:130くらい'))
63
+
64
+ = How to find targets?\n(('note:そんなにネタがあるの?'))
65
+
66
+ Just I needed\n
67
+ (('note:単に自分が必要だったから'))
68
+
69
+ = Today's topic\n(('note:今日の話題'))
70
+
71
+ Overview\n
72
+ what we can do\n
73
+ ((*with Ruby*))\n
74
+ (('note:Rubyでできるようになったことをたくさん紹介'))
75
+
76
+ = Category1\n(('note:分類1'))
77
+
78
+ Web feed\n
79
+ (('note:Webフィード'))
80
+
81
+ = RSS Parser
82
+
83
+ RSS/Atom parser\n
84
+ with\n
85
+ ((*validation*))\n
86
+ (('note:バリデーション機能付きのRSS/Atomパーサー'))
87
+
88
+ = RSS Parser - History\n(('note:歴史'))
89
+
90
+ * 2003-05: The first release\n
91
+ (('note:最初のリリース'))
92
+ * No other RSS/Atom parser that supports validation even now\n
93
+ (('note:今でもバリデーション付きのパーサーは他にない'))
94
+ * 2004-01: Ruby bundles this\n
95
+ (('note:RubyがRSS Parserをバンドル'))
96
+ * I became a Ruby committer\n
97
+ (('note:Rubyコミッターになる'))
98
+
99
+ = Validate RSS/Atom\n(('note:RSS/Atomのバリデーション'))
100
+
101
+ * Important for me\n
102
+ (('note:私にとっては大事'))
103
+ * Most wild RSS/Atom feeds are\n
104
+ ((*invalid*))\n
105
+ (('note:野生のRSS/Atomの多くは不正'))
106
+ * Validation helps to find problems\n
107
+ (('note:バリデーションがあると問題を見つけやすくなる'))
108
+
109
+ = RSS::Parser.parse
110
+
111
+ # coderay ruby
112
+
113
+ # Validates by default
114
+ # デフォルトでバリデーション
115
+ RSS::Parser.parse(rss)
116
+ # Validation can be disabled
117
+ # 無効にできる
118
+ RSS::Parser.parse(rss, false)
119
+
120
+ = Since Ruby 2.6\n(('note:Ruby 2.6以降'))
121
+
122
+ # coderay ruby
123
+
124
+ # Supports keyword argument
125
+ # キーワード引数対応
126
+ parse(rss, validate: false)
127
+
128
+ = REXML
129
+
130
+ XML parser\n
131
+ written in\n
132
+ ((*pure Ruby*))\n
133
+ (('note:Ruby実装のXMLパーサー'))
134
+
135
+ = REXML - History\n(('note:歴史'))
136
+
137
+ * 2001: Started by Sean Russell\n
138
+ (('note:Seanさんが開発を開始'))
139
+ * Based on Electric XML (Java)\n
140
+ (('note:Java実装のElectric XMLを参考に開発'))
141
+ * REXML is "Ruby Electric XML"\n
142
+ (('note:REXMLは「Ruby Electric XML」'))
143
+ * 2003-01: Ruby bundles this\n
144
+ (('note:RubyがREXMLをバンドル'))
145
+
146
+ = REXML - Side story\n(('note:おまけ話'))
147
+
148
+ * Sean was "書運" in Kanji\n
149
+ (('note:Seanさんには「書運」という漢字表記があった'))
150
+ * He was interested in Japan\n
151
+ (('note:日本好きだった'))
152
+ * (('tag:x-small'))"How to write your name in Kanji?"\n
153
+ (('note:「君の名前は漢字でどう書くの?」'))
154
+ * We can connect with Ruby!\n
155
+ (('note:RubyistはRubyをきっかけにつながれる!'))
156
+
157
+ = Ad: Code Party\n(('note:宣伝:コード懇親会'))
158
+
159
+ # img
160
+ # src = images/code-party.png
161
+ # relative_height = 100
162
+ # reflect_ratio = 0.1
163
+
164
+ == Slide properties
165
+
166
+ : enable-title-on-image
167
+ false
168
+
169
+ = Ad: Code Party\n(('note:宣伝:コード懇親会'))
170
+
171
+ (('tag:center'))
172
+ This is a challenge\n
173
+ (('note:実験的な企画'))
174
+
175
+ * Ruby focus to have fun\n
176
+ (('note:Rubyは楽しさを大事にしている'))
177
+ * We have fun writing Ruby\n
178
+ (('note:Rubyistは楽しくRubyを書いている'))
179
+ * We have fun together with writing Ruby at after party!?\n
180
+ (('note:だったら懇親会で一緒にRubyを書くと楽しそう!?'))
181
+
182
+ = Ad: Code Party\n(('note:宣伝:コード懇親会'))
183
+
184
+ * Matz attends Code Party\n
185
+ (('note:まつもとさんもコード懇親会に参加'))
186
+ * Sponsored by Speee, Inc.\n
187
+ (('note:Speeeさんがスポンサー'))
188
+
189
+ = REXML - Recent1\n(('note:最近1'))
190
+
191
+ * 2010-08: RubyKaigi 2010
192
+ * I became the maintainer\n
193
+ (('note:私がメンテナーになった'))
194
+ * Because RSS Parser uses it\n
195
+ (('note:RSS Parserが使っているから'))
196
+
197
+ = REXML - Recent2\n(('note:最近2'))
198
+
199
+ * 2016: (({element[attribute_name]}))
200
+ * Ruby 2.5 ships it\n
201
+ (('note:Ruby 2.5以降で使える'))
202
+
203
+ = REXML - Recent3\n(('note:最近3'))
204
+
205
+ * 2018: Fix XPath related bugs\n
206
+ (('note:XPath関連のバグ修正'))
207
+ * Ruby 2.6 ships it\n
208
+ (('note:Ruby 2.6以降で使える'))
209
+
210
+ = REXML - Future?\n(('note:未来はあるの?'))
211
+
212
+ * ((*Pure Ruby*)) is valuable\n
213
+ (('note:Rubyだけで書かれていることには価値がある'))
214
+ * Easy to install\n
215
+ (('note:インストールが簡単'))
216
+ * JIT may improve performance\n
217
+ (('note:NOTE: We should improve general logic before we expect JIT to improve performance😉'))\n
218
+ (('note:JITで速くなるかもしれない'))\n
219
+ (('note:JITの前に普通にロジックを改良するのが先だけどね😉'))\n
220
+
221
+ = Recent my works\n(('note:最近の仕事'))
222
+
223
+ * XML/HTML libraries for LuaJIT\n
224
+ (('note:LuaJIT用のXML/HTMLライブラリー'))
225
+ * XMLua: (('tag:xx-small:((<URL:https://clear-code.github.io/xmlua/>))'))\n
226
+ libxml2 based XML/HTML parser
227
+ * LuaCS: (('tag:xx-small:((<URL:https://clear-code.github.io/luacs/>))'))\n
228
+ CSS Selectors→XPath converter
229
+ * Found what lacks in REXML API\n
230
+ (('note:REXMLのAPIに足りないものはなにか考えた'))
231
+
232
+ = REXML - Future1\n(('note:機能1'))
233
+
234
+ Introduce NodeSet\n
235
+ (('note:NodeSetが足りないんじゃないか'))
236
+
237
+ = REXML - NodeSet
238
+
239
+ # coderay ruby
240
+ doc.
241
+ search("//item"). # => NodeSet
242
+ text # All texts in <item>
243
+
244
+ = REXML - Future2\n(('note:機能2'))
245
+
246
+ Support\n
247
+ CSS Selectors\n
248
+ (('note:CSSセレクターが足りないんじゃないか'))
249
+
250
+ = REXML - CSS Selectors\n(('note:CSSセレクター'))
251
+
252
+ # coderay ruby
253
+ doc.css_select("ul li, dl dt")
254
+
255
+ = REXML - Future3\n(('note:機能3'))
256
+
257
+ Support\n
258
+ HTML5 support\n
259
+ (('note:HTML5対応が足りないんじゃないか'))
260
+
261
+ = REXML - HTML5
262
+
263
+ # coderay ruby
264
+
265
+ doc = REXML::HTML5Document.new(html5)
266
+ doc.search("//li")
267
+ doc.css_select("ul li")
268
+
269
+ = REXML - Future\n(('note:未来'))
270
+
271
+ * Low priority in my activities\n
272
+ (('note:優先度は高くない'))
273
+ * Do you want to work with me?\n
274
+ (('note:一緒にやりたい人はいる?'))
275
+
276
+ = Category2\n(('note:分類1'))
277
+
278
+ Presentation\n
279
+ (('note:プレゼンテーション'))
280
+
281
+ = Rabbit
282
+
283
+ (('tag:center'))
284
+ (('tag:large'))
285
+ Presentation tool\n
286
+ for ((*Rubyist*))\n
287
+ (('note:Rubyist用のプレゼンツール'))
288
+
289
+ ((' '))
290
+
291
+ = Rabbit - History\n(('note:歴史'))
292
+
293
+ * 2004-07: The first release\n
294
+ (('note:最初のリリース'))
295
+ * No other presentation tool for Rubyist even now\n
296
+ (('note:今でもRubyist用のプレゼンツールは他にない'))
297
+ * 2010: Matz migrated to Rabbit\n
298
+ (('note:まつもとさんがRabbitに乗り換えた'))
299
+ * Since RubyKaigi 2010?\n
300
+ (('note:RubyKaigi 2010から?'))
301
+
302
+ = For Rubyist?\n(('note:Rubyist向けに必要なもの'))
303
+
304
+ RD support\n
305
+ (('note:RDサポート'))
306
+
307
+ = RD
308
+
309
+ * ((*R*))uby ((*D*))ocument\n
310
+ * Designed by Matz (('note:(Right?)'))\n
311
+ (('note:まつもとさんがデザインしたはず'))
312
+ * A text based markup language\n
313
+ (('note:テキストベースのマークアップ言語'))
314
+ * Version controllable\n
315
+ (('note:バージョン管理できる'))
316
+
317
+ = For Rubyist?\n(('note:Rubyist向けに必要なもの'))
318
+
319
+ Publish\n
320
+ our slides\n
321
+ as usual\n
322
+ (('note:いつも通りスライドを公開できる'))
323
+
324
+ = Publish as usual\n(('note:いつも通り公開'))
325
+
326
+ # coderay console
327
+ % gem push your-slide-1.0.gem
328
+
329
+ = Published!\n(('note:公開完了!'))
330
+
331
+ # img
332
+ # src = images/rabbit-slide-show.png
333
+ # relative_height = 78
334
+
335
+ (('tag:center'))
336
+ (('tag:small'))
337
+ ((<URL:https://slide.rabbit-shocker.org/>))
338
+
339
+ = What's needed for presentation tool?\n(('note:プレゼンツールに必要なもの'))
340
+
341
+ GUI
342
+
343
+ = Ruby/GTK3
344
+
345
+ Multi-platform GUI toolkit\n
346
+ (('note:複数プラットフォーム対応GUIツールキット'))
347
+
348
+ = Ruby/GTK3 - History\n(('note:歴史'))
349
+
350
+ * 1998-01: 1st release by Matz\n
351
+ ((<[ruby-list:5877]|URL:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5877>))\n
352
+ (('note:まつもとさんが最初のリリース'))
353
+ * 2004-05: I joined development\n
354
+ (('note:私が開発に参加'))
355
+
356
+ = Example - Window
357
+
358
+ # coderay ruby
359
+ require "gtk3"
360
+ app = Gtk::Application.new
361
+ app.signal_connect(:activate) do
362
+ window = Gtk::ApplicationWindow.new(app)
363
+ window.show_all
364
+ end
365
+ app.run
366
+
367
+ = Approaches on\nmissing libraries(1)\n(('note:ライブラリーがない時のやり方(1)'))
368
+
369
+ (1) Implement only the needed features\n
370
+ (('note:必要な機能だけ実装'))
371
+ (2) then back to Rabbit\n
372
+ (('note:必要な機能ができたらRabbitに戻る'))
373
+
374
+ = Approaches on\nmissing libraries(2)\n(('note:ライブラリーがない時のやり方(2)'))
375
+
376
+ (1) Implement not only the needed features\n
377
+ (('note:必要な機能だけじゃなく'))
378
+ (2) but also (('note:almost')) all features\n
379
+ (('note:ほぼすべての機能を実装'))
380
+ (3) then back to Rabbit\n
381
+ (('note:終わったらRabbitに戻る'))
382
+
383
+ = My approach\n(('note:私のやり方'))
384
+
385
+ Implement\n
386
+ all features\n
387
+ (('note:testing with Rabbit'))\n
388
+ (('note:すべての機能を実装'))
389
+
390
+ = My priority\n(('note:私の優先度'))
391
+
392
+ * Rabbit is important\n
393
+ (('note:Rabbitは大事だけど'))
394
+ * Increasing what Ruby can is also important\n
395
+ (('note:Rubyでできることを増やすのも大事'))
396
+
397
+ = GTK+ 3 - Size\n(('note:サイズ'))
398
+
399
+ 3000 over API\n
400
+ (('note:3000以上のAPI'))
401
+
402
+ = How to implement\n(('note:実装方法'))
403
+
404
+ Handwriting\n
405
+ (('note:手書き'))\n
406
+ ↓\n
407
+ Auto generation\n
408
+ (('note:自動生成'))
409
+
410
+ = Ruby/GI
411
+
412
+ (('tag:center'))
413
+ (('tag:large'))
414
+ Generate bindings\n
415
+ automatically\n
416
+ at run-time\n
417
+ (('note:実行時に自動でバインディングを生成'))
418
+
419
+ (('note:GI: GObject Introspection'))
420
+
421
+ = Ruby/GI - History\n(('note:歴史'))
422
+
423
+ * 2012: The first commit by me\n
424
+ (('note:最初のコミット'))
425
+ * 2014: Ruby/GTK3 used Ruby/GI\n
426
+ (('note:Ruby/GTK3をRuby/GIベースに移行'))
427
+
428
+ = Handwriting\n(('note:手書き'))
429
+
430
+ # img
431
+ # src = images/ruby-gtk3-without-ruby-gi.svg
432
+ # relative_width = 100
433
+
434
+ == Slide properties
435
+
436
+ : enable-title-on-image
437
+ false
438
+
439
+ = Auto generation\n(('note:自動生成'))
440
+
441
+ # img
442
+ # src = images/ruby-gtk3-with-ruby-gi.svg
443
+ # relative_width = 100
444
+
445
+ == Slide properties
446
+
447
+ : enable-title-on-image
448
+ false
449
+
450
+ = Ruby/GI - See also\n(('note:参考情報'))
451
+
452
+ * "How to create bindings 2016" at RubyKaigi 2016\n
453
+ * (('tag:xx-small'))
454
+ ((<URL:http://rubykaigi.org/2016/presentations/ktou.html>))
455
+ * "GI Introduction" (('note:(in Japanese)'))\n
456
+ (('note:「GObject Introspection入門」'))
457
+ * (('tag:xx-small'))
458
+ ((<URL:https://github.com/RubyData/workshop-materials/blob/master/gobject-introspection/introduction.md>))
459
+ * Build system: Meson + Ninja\n
460
+ (('note:ビルドシステム:Meson + Ninja'))
461
+
462
+ = Ruby/GI based bindings\n(('note:Ruby/GIベースのバインディング'))
463
+
464
+ Ruby/Pango
465
+
466
+ = Ruby/Pango
467
+
468
+ (('tag:center'))
469
+ (('tag:large'))
470
+ Text layout engine\n
471
+ with\n
472
+ i18n support\n
473
+ (('note:国際化対応のテキストレイアウトエンジン'))
474
+
475
+ (('note:i18n: Internationalization'))
476
+
477
+ = Prohibition processing\n(('note:禁則処理'))
478
+
479
+ # coderay ruby
480
+
481
+ widget.signal_connect(:draw) do |_, context|
482
+ layout = context.create_pango_layout
483
+ layout.text = "Helloこんにちは。🍣"
484
+ context.show_pango_layout(layout)
485
+ GLib::Source::CONTINUE
486
+ end
487
+
488
+ = Bidirectional text\n(('note:双方向テキスト'))
489
+
490
+ Hello
491
+
492
+ مرحبا
493
+
494
+ こんにちは
495
+
496
+ = Ruby/GI based bindings\n(('note:Ruby/GIベースのバインディング'))
497
+
498
+ Ruby/GdkPixbuf2
499
+
500
+ = Ruby/GdkPixbuf2
501
+
502
+ Image manipulation\n
503
+ (('note:画像操作'))
504
+
505
+ = Half image\n(('note:画像を半分に'))
506
+
507
+ # coderay ruby
508
+
509
+ require "gdk_pixbuf2"
510
+ # Load an image: Format is auto detected
511
+ pixbuf = GdkPixbuf::Pixbuf.new(file: "x.png")
512
+ # Scale to half size
513
+ half = pixbuf.scale(pixbuf.width / 2,
514
+ pixbuf.height / 2,
515
+ :bilinear)
516
+ # Save as different format
517
+ half.save("half.jpg")
518
+
519
+ = Animation GIF\n(('note:アニメーションGIF'))
520
+
521
+ # img
522
+ # src = images/the-tortoise-and-the-hare.gif
523
+ # relative_width = 100
524
+
525
+ == Slide properties
526
+
527
+ : enable-title-on-image
528
+ false
529
+
530
+ = Ruby/GI based bindings\n(('note:Ruby/GIベースのバインディング'))
531
+
532
+ Ruby/Poppler
533
+
534
+ = Ruby/Poppler
535
+
536
+ PDF\n
537
+ parser/renderer\n
538
+ (('note:PDFパーサー・レンダラー'))
539
+
540
+ = Text extraction\n(('note:テキスト抽出'))
541
+
542
+ # coderay ruby
543
+
544
+ require "poppler"
545
+ doc = Poppler::Document.new("x.pdf")
546
+ doc.each do |page|
547
+ puts(page.text) # Extract all texts
548
+ end
549
+
550
+ = Embed PDF\n(('note:PDFの埋め込み'))
551
+
552
+ # image
553
+ # src = images/rubykaigi-2017-extension-by-cpp-title.pdf
554
+ # relative_height = 80
555
+ # reflect_ratio = 0.1
556
+
557
+ (('tag:center'))
558
+ (('tag:xx-small'))
559
+ ((<URL:http://rubykaigi.org/2017/presentations/ktou.html>))
560
+
561
+ == Slide properties
562
+
563
+ : enable-title-on-image
564
+ false
565
+
566
+ = Ruby/GI based bindings\n(('note:Ruby/GIベースのバインディング'))
567
+
568
+ Ruby/GStreamer
569
+
570
+ = Ruby/GStreamer
571
+
572
+ (('tag:center'))
573
+ (('tag:large'))
574
+ Audio/Video player\n
575
+ (('note:音声・動画プレイヤー'))
576
+
577
+ (('note:(*) Streaming media framework'))\n
578
+ (('note:本当はストリーミングメディアフレームワーク'))
579
+
580
+ = Camera(('note:(カメラ)'))
581
+
582
+ # coderay ruby
583
+
584
+ require "gst"
585
+ description = [
586
+ "autovideosrc", # Camera
587
+ "videoconvert", # Filter
588
+ "autovideosink", # Window
589
+ ].join(" ! ")
590
+ pipeline = Gst.parse_launch(description)
591
+ pipeline.play
592
+ until pipeline.bus.poll.type.eos? do
593
+ end # Main loop
594
+ pipeline.stop
595
+
596
+ = Face detection\n(('note:顔認識'))
597
+
598
+ # coderay ruby
599
+
600
+ description = [
601
+ "autovideosrc", # Camera
602
+ "videoconvert", # Filter
603
+ "facedetect", # Face detection (!)
604
+ "videoconvert", # Filter (!)
605
+ "autovideosink", # Window
606
+ ].join(" ! ")
607
+ pipeline = Gst.parse_launch(description)
608
+ pipeline.play
609
+
610
+ # = Embed video
611
+
612
+ # TODO
613
+
614
+ # # # video
615
+ # # # src = test.mp4
616
+
617
+ = What's needed for presentation tool?\n(('note:プレゼンツールに必要なもの'))
618
+
619
+ PDF output\n
620
+ (('note:PDF出力'))
621
+
622
+ = rcairo
623
+
624
+ 2D graphics renderer\n
625
+ (('note:2次元画像レンダラー'))
626
+
627
+ = rcairo - Outputs\n(('note:出力'))
628
+
629
+ * PNG・SVG
630
+ * ((*PDF*))
631
+ * ((*Display*)) (X/macOS/Windows)
632
+ * ...
633
+
634
+ = rcairo - History\n(('note:歴史'))
635
+
636
+ * 2003-10: The initial commit\n
637
+ (('note:最初のコミット'))
638
+ * 2005-09: I started developing\n
639
+ (('note:私が開発に参加'))
640
+
641
+ = Red A4 PDF\n(('note:赤いA4のPDFを出力'))
642
+
643
+ # coderay ruby
644
+
645
+ require "cairo"
646
+ include Cairo
647
+ PDFSurface.create("x.pdf", "A4") do |surface|
648
+ Context.create(surface) do |context|
649
+ context.set_source_color(:red)
650
+ context.paint
651
+ end
652
+ end
653
+
654
+ = rcairo - GC
655
+
656
+ # image
657
+ # src = images/cairo-no-gc-trigger.pdf
658
+ # align = right
659
+ # vertical_align = bottom
660
+ # relative_width = 65
661
+ # relative_padding_right = -7
662
+ # relative_padding_bottom = -10
663
+
664
+ # coderay ruby
665
+ 1000.times do
666
+ Cairo::ImageSurface.new(:argb32, 6000, 6000)
667
+ end
668
+
669
+ (('tag:margin-bottom * 20'))
670
+
671
+ = GC - Cause(('note:(原因)'))
672
+
673
+ # image
674
+ # src = images/cairo-no-gc-trigger.pdf
675
+ # align = right
676
+ # vertical_align = bottom
677
+ # relative_width = 67
678
+ # relative_padding_right = -11
679
+ # relative_padding_bottom = -10
680
+
681
+ * GC isn't ran enough frequency\n
682
+ (('note:GCの実行頻度が十分じゃなかった'))
683
+ * Because Ruby doesn't know how many memory used by cairo\n
684
+ (('note:Rubyはcairoのメモリー使用量を知らないから'))
685
+
686
+ (('tag:margin-bottom * 16'))
687
+
688
+ = GC - Fix(('note:(修正)'))
689
+
690
+ # image
691
+ # src = images/cairo-gc-trigger.pdf
692
+ # align = right
693
+ # vertical_align = bottom
694
+ # relative_width = 67
695
+ # relative_padding_right = -11
696
+ # relative_padding_bottom = -10
697
+
698
+ * (({rb_gc_adjust_memory_usage()}))
699
+ * Improve GC frequency(('note:(GC実行頻度を改善)'))
700
+ * Ruby 2.4 ships it(('note:(Ruby 2.4以降)'))
701
+
702
+ (('tag:margin-bottom * 18'))
703
+
704
+ = Easy to install\n(('note:簡単インストール'))
705
+
706
+ Important\n
707
+ (('note:大事'))
708
+
709
+ = native-package-installer
710
+
711
+ Install\n
712
+ system packages\n
713
+ on (({gem install}))\n
714
+ (('note:gem install時にシステムのパッケージをインストール'))
715
+
716
+ = extconf.rb/Rakefile
717
+
718
+ # coderay ruby
719
+
720
+ require "pkg-config"
721
+ require "native-package-installer"
722
+ unless PKGConfig.check_version?("gdk-3.0")
723
+ packages = {
724
+ altlinux: "libgtk+3-devel",
725
+ debian: "libgtk-3-dev",
726
+ redhat: "pkgconfig(gdk-3.0)",
727
+ homebrew: "gtk+3",
728
+ macports: "gtk3",
729
+ msys2: "gtk3",
730
+ }
731
+ unless NativePackageInstaller.install(packages)
732
+ exit(false)
733
+ end
734
+ end
735
+
736
+ = rake-compiler
737
+
738
+ Build fat gem\n
739
+ by\n
740
+ cross compile\n
741
+ (('note:クロスコンパイルでfat gemをビルド'))
742
+
743
+ = rake-compiler - History\n(('note:歴史'))
744
+
745
+ * 2008-11: The first commit\n
746
+ (('note:最初のコミット'))
747
+ * 2014-12: Orphan\n
748
+ (('note:だれかメンテナー変わってー'))
749
+ * 2014-12:\n
750
+ I became the maintainer\n
751
+ (('note:私がメンテナーになった'))
752
+
753
+ = Category3\n(('note:分類3'))
754
+
755
+ Test\n
756
+ (('note:テスト'))
757
+
758
+ = test-unit
759
+
760
+ Testing framework\n
761
+ to write tests\n
762
+ ((*in Ruby*))\n
763
+ (('note:Rubyでテストを書けるテスティングフレームワーク'))
764
+
765
+ = test-unit - History\n(('note:歴史'))
766
+
767
+ * 2003-02: Import to Ruby\n
768
+ (('note:Rubyに取り込まれる'))
769
+ * 2008-05:\n
770
+ I became the maintainer\n
771
+ (('note:私がメンテナーになった'))
772
+ * 2008-10: Removed from Ruby\n
773
+ (('note:Rubyから削除'))
774
+
775
+ (('note:See also: "The history of testing framework in Ruby"'))\n
776
+ (('tag:x-small'))((<URL:http://rubykaigi.org/2015/presentations/kou>))
777
+
778
+ = test-unit - New feature\n(('note:新機能'))
779
+
780
+ Grouping\n
781
+ (('note:グループ化'))
782
+
783
+ = Grouping\n(('note:グループ化'))
784
+
785
+ * The most important feature\n
786
+ (('note:一番大事な機能'))
787
+ * Keep tests maintainable\n
788
+ (('note:メンテナンスできるテストを維持できる'))
789
+
790
+ = Example(('note:(例)'))
791
+
792
+ # coderay ruby
793
+
794
+ class StackTest < Test::Unit::TestCase
795
+ class PushTest < self
796
+ def test_XXX; end
797
+ end
798
+ class PopTest < self
799
+ def test_XXX; end
800
+ end
801
+ end
802
+
803
+ = Method style(('note:(メソッド形式)'))
804
+
805
+ # coderay ruby
806
+
807
+ class StackTest < Test::Unit::TestCase
808
+ sub_test_case("#push") do
809
+ def test_XXX; end
810
+ end
811
+ sub_test_case("#pop") do
812
+ def test_XXX; end
813
+ end
814
+ end
815
+
816
+ = test-unit - New feature\n(('note:新機能'))
817
+
818
+ Data driven test\n
819
+ (('note:データ駆動テスト'))
820
+
821
+ = Data driven test\n(('note:データ駆動テスト'))
822
+
823
+ # coderay ruby
824
+
825
+ data("positive", [3, 1, 2])
826
+ data("negative", [-4, 1, -5])
827
+ def test_add(data)
828
+ expected, augend, addend = data
829
+ assert_equal(expected,
830
+ add(augend, addend))
831
+ end
832
+
833
+ = test-unit - New feature\n(('note:新機能'))
834
+
835
+ Reverse backtrace\n
836
+ (('note:逆順のバックトレース'))
837
+
838
+ = Reverse backtrace\n(('note:逆順のバックトレース'))
839
+
840
+ * Reverse backtrace only when terminal output\n
841
+ (('note:ターミナル出力のときだけ逆順'))
842
+ * The same change as Ruby 2.5.0\n
843
+ (('note:Ruby 2.5.0と同じ変更'))
844
+
845
+ = test-unit - New feature\n(('note:新機能'))
846
+
847
+ Test double\n
848
+ (('note:テストダブル'))
849
+
850
+ = test-unit-rr
851
+
852
+ RR integration\n
853
+ (('note:RRとの統合'))
854
+
855
+ = RR - History\n(('note:歴史'))
856
+
857
+ * 2007-06: The initial commit\n
858
+ (('note:最初のコミット'))
859
+ * 2014-12: Orphan\n
860
+ (('note:だれかメンテナー変わってー'))
861
+ * 2015-05:\n
862
+ I became the maintainer\n
863
+ (('note:私がメンテナーになった'))
864
+
865
+ = Stub(('note:(スタブ)'))
866
+
867
+ # coderay ruby
868
+
869
+ adder = Object.new
870
+ adder.add(1, 2) # => Error
871
+ stub(adder).add(1, 2) {3}
872
+ adder.add(1, 2) # => 3
873
+
874
+ = Category4\n(('note:分類4'))
875
+
876
+ Full text search\n
877
+ (('note:全文検索'))
878
+
879
+ = Rroonga
880
+
881
+ Full text search\n
882
+ ((*library*))\n
883
+ (('note:全文検索ライブラリー'))
884
+
885
+ = ((*Library*)) vs Client\n(('note:ライブラリー対クライアント'))
886
+
887
+ * No server process\n
888
+ (('note:サーバープロセスがいらない'))
889
+ * Easy to start\n
890
+ (('note:簡単に使い始められる'))
891
+ * Write in Ruby\n
892
+ (('note:Rubyで書ける'))
893
+
894
+ = Create DB(('note:(データベース作成)'))
895
+
896
+ # coderay ruby
897
+ require "groonga"
898
+
899
+ Groonga::Database.create(path: "/tmp/db")
900
+
901
+ = Define schema(('note:(スキーマ定義)'))
902
+
903
+ # coderay ruby
904
+
905
+ Groonga::Schema.define do |schema|
906
+ schema.create_table("docs") do |table|
907
+ # The column to store text
908
+ table.text("content")
909
+ end
910
+ # The index for full text search
911
+ schema.create_lexicon("terms") do |table|
912
+ table.index("docs.content")
913
+ end
914
+ end
915
+
916
+ = Add records(('note:(レコード追加)'))
917
+
918
+ # coderay ruby
919
+
920
+ docs = Groonga["docs"]
921
+ docs.add(content: "String#<< concatenates ...")
922
+ docs.add(content: "String#dup duplicates ...")
923
+
924
+ = Search(('note:(検索)'))
925
+
926
+ # coderay ruby
927
+
928
+ matches = docs.select do |record|
929
+ record.content.match("concat")
930
+ end
931
+ p matches.size # => 1
932
+ matches.each do |record|
933
+ p record.content # => "String#<< concat..."
934
+ end
935
+
936
+ = User - Rabbit Slide Show
937
+
938
+ # img
939
+ # src = images/rabbit-slide-show.png
940
+ # relative_height = 78
941
+
942
+ (('tag:center'))
943
+ (('tag:small'))
944
+ ((<URL:https://slide.rabbit-shocker.org/>))
945
+
946
+ = User - Rurema Search
947
+
948
+ # img
949
+ # src = images/rurema-search.png
950
+ # relative_height = 78
951
+
952
+ (('tag:center'))
953
+ (('tag:small'))
954
+ ((<URL:https://docs.ruby-lang.org/ja/search/>))
955
+
956
+ = Rurema Search\n(('note:るりまサーチ'))
957
+
958
+ * Super fast!\n
959
+ (('note:すごく速い!'))
960
+ * Tune for programming document\n
961
+ (('note:プログラミングのドキュメント用にチューニング'))
962
+ * Symbols (@, #, ...) are important\n
963
+ (('note:@とか#とかの記号も大事'))
964
+
965
+ = User - RDoc Search
966
+
967
+ * Planning\n
968
+ (('note:考えてはいるけど。。。'))
969
+ * Do you want to work with me?\n
970
+ (('note:一緒にやりたい人はいる?'))
971
+
972
+ = Rurema and RDoc
973
+
974
+ # RT
975
+
976
+ Project, Language, Target
977
+
978
+ Rurema, Japanese, Japanese Rubyists
979
+ RDoc, English, All Rubyists
980
+
981
+ = Source\n(('note:ソース'))
982
+
983
+ * Shared nothing\n
984
+ (('note:共有していない'))
985
+ * Copy based share\n
986
+ (('note:共有するときはコピー'))
987
+ * e.g.:\n
988
+ Description,\n
989
+ Sample codes,\n
990
+ ...\n
991
+ (('note:例:説明やサンプルコードなどをコピー'))
992
+
993
+ = From my point of view\n(('note:私が思うこと'))
994
+
995
+ * Can we share documents?\n
996
+ (('note:ドキュメントを共有できないかな'))
997
+ * How to work together deeply?\n
998
+ (('note:もっと協力してできないかな'))
999
+
1000
+ = I18n\n(('note:国際化'))
1001
+
1002
+ * Source: RDoc\n
1003
+ (('note:ソースはRDoc'))
1004
+ * For all Rubyists\n
1005
+ (('note:これは全Rubyist向け'))
1006
+ * Translate to Japanese\n
1007
+ (('note:RDocのドキュメントを日本語に翻訳'))
1008
+ * For Japanese Rubyists\n
1009
+ (('note:これは日本人Rubyist向け'))
1010
+
1011
+ = Add i18n support\n(('note:国際化サポートを追加'))
1012
+
1013
+ * YARD
1014
+ * Since 0.8.0 at 2012-04
1015
+ * RDoc
1016
+ * Since 4.2.0 at 2014-12
1017
+
1018
+ = YARD - i18n
1019
+
1020
+ # coderay console
1021
+
1022
+ # Generates po/yard.pot
1023
+ # po/yard.potを生成
1024
+ % yard i18n
1025
+
1026
+ = YARD - i18n
1027
+
1028
+ # coderay console
1029
+
1030
+ # Create po/ja.po from po/yard.pot
1031
+ # po/yard.potからpo/ja.poを作成
1032
+ % msginit \
1033
+ --locale=ja_JP.UTF-8 \
1034
+ --input=po/yard.pot \
1035
+ --output-file=po/ja.po
1036
+
1037
+ = YARD - i18n
1038
+
1039
+ # coderay console
1040
+
1041
+ # Translate messages in po/ja.po
1042
+ # po/ja.po内のメッセージを翻訳
1043
+ % editor po/ja.po
1044
+
1045
+ = YARD - i18n
1046
+
1047
+ # coderay console
1048
+
1049
+ # Generate documents with
1050
+ # translated messages
1051
+ # 翻訳したメッセージを使って
1052
+ # ドキュメント生成
1053
+ % yard --locale ja
1054
+
1055
+ = Packnga
1056
+
1057
+ Rake task\n
1058
+ for\n
1059
+ YARD i18n\n
1060
+ (('note:YARDの国際化機能向けのRakeタスク'))
1061
+
1062
+ = Setting\n(('note:設定'))
1063
+
1064
+ # coderay ruby
1065
+
1066
+ # Rakefile
1067
+ require "packnga"
1068
+ Packnga::DocumentTask.new(spec) do |task|
1069
+ task.original_language = "en"
1070
+ task.translate_languages = ["ja"]
1071
+ end
1072
+
1073
+ = Workflow\n(('note:ワークフロー'))
1074
+
1075
+ # coderay console
1076
+
1077
+ % rake reference:translate
1078
+ % editor doc/po/ja/x.edit.po
1079
+ % rake reference:translate
1080
+ % editor lib/x.rb
1081
+ % rake reference:translate
1082
+ ...
1083
+
1084
+ = Users\n(('note:ユーザー'))
1085
+
1086
+ * test-unit
1087
+ * Rroonga
1088
+ * ...
1089
+
1090
+ = RDoc - i18n
1091
+
1092
+ # coderay console
1093
+
1094
+ # Generates doc/rdoc.pot
1095
+ # doc/rdoc.potを生成
1096
+ % rdoc --format=pot
1097
+
1098
+ = RDoc - i18n
1099
+
1100
+ # coderay console
1101
+
1102
+ # Create locale/ja.po
1103
+ # from doc/rdoc.pot
1104
+ # doc/rdoc.potからlocale/ja.poを作成
1105
+ % mkdir -p locale
1106
+ % msginit \
1107
+ --locale=ja_JP.UTF-8 \
1108
+ --input=doc/rdoc.pot \
1109
+ --output-file=locale/ja.po
1110
+
1111
+ = RDoc - i18n
1112
+
1113
+ # coderay console
1114
+
1115
+ # Translate messages in locale/ja.po
1116
+ # locale/ja.po内のメッセージを翻訳
1117
+ % editor locale/ja.po
1118
+
1119
+ = RDoc - i18n
1120
+
1121
+ # coderay console
1122
+
1123
+ # Generate documents with
1124
+ # translated messages
1125
+ # 翻訳したメッセージを使って
1126
+ # ドキュメント生成
1127
+ % rdoc --locale ja
1128
+
1129
+ = RDoc, Rurema and i18n
1130
+
1131
+ * No progress...\n
1132
+ (('note:ツールの整備まででそれ以降は進んでいない。。。'))
1133
+ * Do you want to work with me?\n
1134
+ (('note:一緒にやりたい人はいる?'))
1135
+
1136
+ = jekyll-task-i18n
1137
+
1138
+ Jekyll + i18n
1139
+
1140
+ = Features\n(('note:機能'))
1141
+
1142
+ * Support all markups!\n
1143
+ (('note:すべてのマークアップ対応!'))
1144
+ * GitHub Pages ready!\n
1145
+ (('note:GitHub Pagesでも使える!'))
1146
+
1147
+ = Setting(('note:(設定)'))
1148
+
1149
+ # coderay ruby
1150
+
1151
+ # Rakefile
1152
+ require "jekyll/task/i18n"
1153
+ Jekyll::Task::I18n.define do |task|
1154
+ task.locales = ["ja"]
1155
+ task.files = Rake::FileList["**/*.md"]
1156
+ task.files -= Rake::FileList["_*/**/*.md"]
1157
+ task.locales.each do |locale|
1158
+ task.files -= Rake::FileList["#{locale}/**/*.md"]
1159
+ end
1160
+ end
1161
+ task default: ["jekyll:i18n:translate"]
1162
+
1163
+ = Workflow(('note:(ワークフロー)'))
1164
+
1165
+ % editor index.md
1166
+ % rake
1167
+ % editor _po/ja/index.edit.po
1168
+ % rake
1169
+ % git commit -a
1170
+
1171
+ = User - Red Data Tools
1172
+
1173
+ # img
1174
+ # src = images/jekyll-task-i18n-red-data-tools.gif
1175
+ # relative_height = 78
1176
+
1177
+ (('tag:center'))
1178
+ (('tag:small'))
1179
+ ((<URL:https://red-data-tools.github.io/>))
1180
+
1181
+ = groonga-client
1182
+
1183
+ Full text search\n
1184
+ ((*client*))\n
1185
+ (('note:全文検索クライアント'))
1186
+
1187
+ = Library vs ((*Client*))\n(('note:ライブラリー対クライアント'))
1188
+
1189
+ * Less dependencies\n
1190
+ (('note:依存関係が少ない'))
1191
+ * Less needed resource\n
1192
+ (('note:必要なリソースが少ない'))
1193
+
1194
+ = Search(('note:(検索)'))
1195
+
1196
+ # coderay ruby
1197
+
1198
+ require "groonga/client"
1199
+ url = "http://localhost:10041"
1200
+ Groonga::Client.open(url: url) do |client|
1201
+ response =
1202
+ client.select(table: "docs",
1203
+ match_columns: "content",
1204
+ query: "concat")
1205
+ p response.n_hits # => 1
1206
+ end
1207
+
1208
+ = Asynchronous(('note:(非同期)'))
1209
+
1210
+ # coderay ruby
1211
+
1212
+ # Call with block
1213
+ client.select(table: "docs",
1214
+ match_columns: "content",
1215
+ query: "concat") do |response|
1216
+ p response.n_hits # => 1
1217
+ end
1218
+ p :here # => :here then ↑
1219
+ sleep(0.1)
1220
+
1221
+ = Asynchronous - wait
1222
+
1223
+ # coderay ruby
1224
+
1225
+ request =
1226
+ client.select(table: "docs",
1227
+ match_columns: "content",
1228
+ query: "concat") do |response|
1229
+ p response.n_hits # => 1
1230
+ end
1231
+ p :here # => :here then ↑
1232
+ request.wait
1233
+
1234
+ = groonga-client-rails
1235
+
1236
+ Ruby on Rails\n
1237
+ integration\n
1238
+ for\n
1239
+ groonga-client\n
1240
+ (('note:Ruby on Railsで使う'))
1241
+
1242
+ = Architecture\n(('note:アーキテクチャー'))
1243
+
1244
+ * Data: RDBMS\n
1245
+ (('note:データはRDBMSに格納'))
1246
+ * Full text search: Groonga\n
1247
+ (('note:全文検索はGroongaで処理'))
1248
+
1249
+ = Define app searcher\n(('note:アプリ用サーチャーを定義'))
1250
+
1251
+ # coderay ruby
1252
+
1253
+ # app/searchers/application_searcher.rb
1254
+ class ApplicationSearcher <
1255
+ Groonga::Client::Searcher
1256
+ end
1257
+
1258
+ = Define searcher\n(('note:サーチャーを定義'))
1259
+
1260
+ # coderay ruby
1261
+
1262
+ # app/searchers/document_searcher.rb
1263
+ class DocumentsSearcher < ApplicationSearcher
1264
+ # Define a full text search index as "content"
1265
+ # 全文検索用のインデックスを定義
1266
+ schema.column :content, {
1267
+ type: "Text",
1268
+ index: true,
1269
+ index_type: :full_text_search,
1270
+ }
1271
+ end
1272
+
1273
+ = Bind to model\n(('note:モデルと結びつける'))
1274
+
1275
+ # coderay ruby
1276
+
1277
+ # app/models/document.rb
1278
+ class Document < ApplicationRecord
1279
+ # DocumentsSearcher searches Document model
1280
+ source = DocumentsSearcher.source(self)
1281
+ # Bind Document's "content" column to
1282
+ # DocumentsSearcher's "content" index
1283
+ source.content = :content
1284
+ end
1285
+
1286
+ = Search(('note:(検索)'))
1287
+
1288
+ # coderay ruby
1289
+
1290
+ # app/controllers/documents_controller.rb
1291
+ class DocumentsController < ApplicationController
1292
+ def index
1293
+ @query = params[:query]
1294
+ searcher = DocumentSearcher.new
1295
+ @result_set = searcher.search.
1296
+ query(@query).
1297
+ result_set
1298
+ end
1299
+ end
1300
+
1301
+ = See also\n(('note:参考情報'))
1302
+
1303
+ * Tutorial in Japanese\n
1304
+ (('note:日本語のチュートリアル'))
1305
+ * (('tag:xx-small'))
1306
+ ((<URL:http://www.clear-code.com/blog/2016/12/22.html>))
1307
+
1308
+ = Groonga
1309
+
1310
+ mruby embedded\n
1311
+ full text search engine\n
1312
+ (('note:mruby組込の全文検索エンジン'))
1313
+
1314
+ = How mruby is used?\n(('note:mrubyの使い方'))
1315
+
1316
+ * Optimizer\n
1317
+ (('note:オプティマイザー'))
1318
+ * Custom command\n
1319
+ (('note:カスタムコマンド'))
1320
+
1321
+ = Custom command\n(('note:カスタムコマンド'))
1322
+
1323
+ # coderay ruby
1324
+
1325
+ module Sharding
1326
+ class LogicalSelectCommand < Groonga::Command
1327
+ # ...
1328
+ end
1329
+ end
1330
+
1331
+ = Use cases\n(('note:利用例'))
1332
+
1333
+ * Redmine plugin\n
1334
+ (('note:Redmineのプラグイン'))
1335
+ * (('tag:x-small'))
1336
+ Repository: ((<URL:https://github.com/clear-code/redmine_full_text_search>))
1337
+ * (('tag:x-small'))
1338
+ Slide (in Japanese): ((<URL:https://slide.rabbit-shocker.org/authors/kou/redmine-tokyo-12/>))
1339
+ * ...
1340
+
1341
+ = Ranguba (WIP)(('note:(開発中)'))
1342
+
1343
+ Full text search system\n
1344
+ (('note:全文検索システム'))
1345
+
1346
+ = Use cases\n(('note:利用例'))
1347
+
1348
+ * File server search\n
1349
+ (('note:ファイルサーバー検索'))
1350
+ * Mail search\n
1351
+ (('note:メール検索'))
1352
+ * Web site search\n
1353
+ (('note:Webサイト検索'))
1354
+
1355
+ = Features\n(('note:機能'))
1356
+
1357
+ * Crawlers\n
1358
+ (('note:クローラー'))
1359
+ * Web UI
1360
+ * CLI
1361
+ * Update documents\n
1362
+ (('note:更新'))
1363
+ * Search documents\n
1364
+ (('note:検索'))
1365
+
1366
+ = ChupaText
1367
+
1368
+ Text extractor\n
1369
+ (('note:テキスト抽出'))
1370
+
1371
+ = Supported formats\n(('note:対応フォーマット'))
1372
+
1373
+ * PDF
1374
+ * Office documents(('note:(オフィス文書)'))
1375
+ * OpenDocument, Word, Excel, ...
1376
+ * E-mail(('note:(メール)'))
1377
+ * ...
1378
+
1379
+ = Interface\n(('note:インターフェイス'))
1380
+
1381
+ * HTTP
1382
+ * Web UI
1383
+ * CLI
1384
+ * API (Library)
1385
+
1386
+ = Install - Docker
1387
+
1388
+ # coderay console
1389
+ % GITHUB=https://github.com
1390
+ % git clone \
1391
+ ${GITHUB}/ranguba/chupa-text-docker.git
1392
+ % cd chupa-text-docker
1393
+ % docker-compose up --build
1394
+
1395
+ = How to use\n(('note:使い方'))
1396
+
1397
+ # coderay console
1398
+ % curl \
1399
+ --form data=@XXX.pdf \
1400
+ http://localhost:20080/extraction.json
1401
+
1402
+ = Use cases\n(('note:利用例'))
1403
+
1404
+ * Ranguba
1405
+ * Full text search system\n
1406
+ (('note:全文検索システム'))
1407
+ * Commit e-mail\n
1408
+ (('note:コミットメール'))
1409
+
1410
+ = git-commit-mailer
1411
+
1412
+ Commit e-mail for Git\n
1413
+ (('note:Git用のコミットメール'))
1414
+
1415
+ = Features\n(('note:機能'))
1416
+
1417
+ * HTML mail\n
1418
+ (('note:HTMLメール'))
1419
+ * Highlighted diff\n
1420
+ (('note:diffをハイライト'))
1421
+ * GitLab/GitHub Web hook support\n
1422
+ (('note:GitLab/GitHubのWebフックをサポート'))
1423
+ * (('tag:xx-small'))
1424
+ By ((<"GitHub:clear-code/github-web-hooks-receiver"|URL:https://github.com/clear-code/github-web-hooks-receiver>))
1425
+
1426
+ = Users\n(('note:利用者'))
1427
+
1428
+ * tDiary
1429
+ * My products
1430
+
1431
+ = commit-email.info
1432
+
1433
+ Commit e-mail\n
1434
+ as a\n
1435
+ Service\n
1436
+ (('note:コミットメールのクラウドサービス'))
1437
+
1438
+ = How to use\n(('note:使い方'))
1439
+
1440
+ * Send a pull request to\n
1441
+ ((<"GitHub:kou/commit-email.info"|URL:https://github.com/kou/commit-email.info>))\n
1442
+ (('note:pull requestを送る'))
1443
+ * Register a Web hook\n
1444
+ (('note:Webフックを登録'))
1445
+ * Subscribe your mailing list\n
1446
+ (('note:メーリングリストを購読'))
1447
+
1448
+ (('note:See also ((<URL:http://www.commit-email.info/>))'))
1449
+
1450
+ = Category5\n(('note:分類5'))
1451
+
1452
+ Data processing\n
1453
+ (('note:データ処理'))
1454
+
1455
+ = csv
1456
+
1457
+ CSV parser\n
1458
+ (('note:CSVパーサー'))
1459
+
1460
+ = csv - History\n(('note:歴史'))
1461
+
1462
+ * 2003: Import\n
1463
+ (('note:Rubyに取り込み'))
1464
+ * 2007: Replaced with FasterCSV\n
1465
+ (('note:FasterCSVで置き換え'))
1466
+ * 2018: I became a co-maintainer with mrkn\n
1467
+ (('note:mrknと一緒にメンテナーになった'))
1468
+
1469
+ = Why?\n(('note:なんで?'))
1470
+
1471
+ * There are many CSV data\n
1472
+ (('note:CSVのデータはたくさんある'))
1473
+ * Important to process data\n
1474
+ (('note:データを処理するためにCSVパーサーは重要'))
1475
+
1476
+ = CSV format problems\n(('note:CSVフォーマットの問題'))
1477
+
1478
+ * Slow to parse\n
1479
+ (('note:パースが遅い'))
1480
+ * Too wild\n
1481
+ (('note:なんでもあり'))
1482
+
1483
+ = Red Arrow
1484
+
1485
+ Apache Arrow Ruby
1486
+
1487
+ = Red Arrow - History\n(('note:歴史'))
1488
+
1489
+ * 2017-02: The first commit\n
1490
+ (('note:最初のコミット'))
1491
+ * 2018-05: Became the "official" Ruby bindings of Apache Arrow\n
1492
+ (('note:Apache Arrowの公式Rubyバインディングになった'))
1493
+
1494
+ = Apache Arrow
1495
+
1496
+ * Super fast data format\n
1497
+ (('note:すごく速いデータフォーマット'))
1498
+ * For in-memory data\n
1499
+ (('note:インメモリーデータ用'))
1500
+ * Cross-language support\n
1501
+ (('note:いろんな言語がサポート'))
1502
+ * Easy to share data with Python, Java, ...\n
1503
+ (('note:PythonやJavaなどとデータ交換がしやすい'))
1504
+
1505
+ = Apache Arrow - Position\n(('note:立ち位置'))
1506
+
1507
+ * A very important peace\n
1508
+ in recent data processing\n
1509
+ (('note:最近のデータ処理界隈ではすごく大事な1ピース'))
1510
+ * Like JIT for Ruby 3\n
1511
+ (('note:Ruby 3で例えるとJITみたいな感じ'))
1512
+
1513
+ = Red Arrow - Impl.\n(('note:実装'))
1514
+
1515
+ * Based on Ruby/GI\n
1516
+ (('note:Ruby/GIを使っている'))
1517
+ * Auto generated bindings\n
1518
+ (('note:バインディングを自動生成'))
1519
+
1520
+ = Red Data Tools
1521
+
1522
+ A project to make Ruby data processable\n
1523
+ (('note:Rubyでデータ処理できるようにするためのプロジェクト'))
1524
+
1525
+ = Red Data Tools - History\n(('note:歴史'))
1526
+
1527
+ * 2017-02: Start(('note:(開始)'))
1528
+ * 2017-11-: Develop events per month at Tokyo at Speee. Inc,\n
1529
+ (('note:東京のSpeeeさんで毎月開発イベントを開催'))
1530
+
1531
+ = The number of products\n(('note:プロダクト数'))
1532
+
1533
+ About 20\n
1534
+ (('note:20くらい'))
1535
+
1536
+ = Red Datasets
1537
+
1538
+ Dataset fetcher\n
1539
+ (('note:データセット取得'))
1540
+
1541
+ = Supported datasets\n(('note:対応データセット'))
1542
+
1543
+ * Iris
1544
+ * CIFAR
1545
+ * Wikipedia
1546
+
1547
+ = Wikipedia
1548
+
1549
+ # coderay ruby
1550
+
1551
+ require "datasets"
1552
+
1553
+ wikipedia = Datasets::WikiPedia.new
1554
+ wikipedia.each do |page|
1555
+ p page.title
1556
+ end
1557
+
1558
+ = Wikipedia search
1559
+
1560
+ # coderay ruby
1561
+
1562
+ pages = Groonga["pages"]
1563
+ wikipedia = Datasets::WikiPedia.new
1564
+ wikipedia.each do |page|
1565
+ pages.add(title: page.title,
1566
+ content: page.revision.text)
1567
+ end
1568
+ ruby_pages = pages.select do |record|
1569
+ record.match("Ruby")
1570
+ end
1571
+ p ruby_pages.n_hits
1572
+
1573
+ = jekyll-jupyter-notebook
1574
+
1575
+ Jekyll\n
1576
+ (('+'))\n
1577
+ Jupyter Notebook
1578
+
1579
+ = Usage\n(('note:使い方'))
1580
+
1581
+ {% jupyter_notebook sample.ipynb %}
1582
+
1583
+ = Red OpenCV
1584
+
1585
+ Computer vision\n
1586
+ (('note:コンピュータービジョン'))
1587
+
1588
+ = Camera(('note:(カメラ)'))
1589
+
1590
+ # coderay ruby
1591
+
1592
+ require "cv"
1593
+ camera = CV::Camera.new
1594
+ image = camera.read
1595
+ image.write("capture.jpg")
1596
+
1597
+ = Face detect(('note:(顔認識)'))
1598
+
1599
+ # coderay ruby
1600
+
1601
+ image_gray = image.convert_color(:bgr2gray)
1602
+ classifier = # Face detector
1603
+ CV::CascadeClassifier.new("frontalface_alt")
1604
+ objects = classifier.detect(image_gray)
1605
+ color = CV::Color.new(0, 0, 255)
1606
+ objects.each do |object|
1607
+ # Draw detected area
1608
+ image.draw_rectangle(object, color)
1609
+ end
1610
+ image.write("detect.jpg")
1611
+
1612
+ = Red OpenCV - Impl.\n(('note:実装'))
1613
+
1614
+ * Based on Ruby/GI\n
1615
+ (('note:Ruby/GIを使っている'))
1616
+ * Auto generated bindings\n
1617
+ (('note:バインディングを自動生成'))
1618
+
1619
+ = Ad: RubyData Workshop\n(('note:宣伝:RubyDataワークショップ'))
1620
+
1621
+ * 2018-06-01 15:50/17:20
1622
+ * Contents:(('note:(内容)'))
1623
+ * Workshop by mrkn\n
1624
+ (('note:mrknによるワークショップ'))
1625
+ * Presentations what Red Data Tools did by members\n
1626
+ (('note:Red Data ToolsメンバーによるRed Data Toolsでやってきたことの紹介'))
1627
+
1628
+ = Process data with Ruby\n(('note:Rubyでデータ処理'))
1629
+
1630
+ * We're working on it\n
1631
+ (('note:Red Data Toolsは継続して取り組んでいる'))
1632
+ * Do you want to work with us?\n
1633
+ (('note:一緒にやりたい人はいる?'))
1634
+
1635
+ = How to join1(('note:(参加方法1)'))
1636
+
1637
+ * Join our chat rooms:\n
1638
+ (('note:チャットルームに参加'))
1639
+ * en: ((<"Gitter:red-data-tools/en"|URL:https://gitter.im/red-data-tools/en>))
1640
+ * ja: ((<"Gitter:red-data-tools/ja"|URL:https://gitter.im/red-data-tools/ja>))
1641
+ * Join monthly events at Tokyo\n
1642
+ (('note:東京での毎月の開発イベントに参加'))
1643
+ * ((<URL:https://speee.connpass.com/>))
1644
+
1645
+ = How to join2(('note:(参加方法2)'))
1646
+
1647
+ * Hire a developer to work on\n
1648
+ (('note:この問題に取り組む開発者を雇う'))
1649
+ * e.g.: mrkn by Speee, Inc.\n
1650
+ (('note:例:Speeeのmrkn'))
1651
+
1652
+ = How to join3(('note:(参加方法3)'))
1653
+
1654
+ * Order ClearCode to work on it\n
1655
+ (('note:クリアコードに開発の仕事を発注'))
1656
+ * Join ClearCode to work on it\n
1657
+ (('note:クリアコードに入って仕事として開発を進める'))
1658
+
1659
+ = Wrap up\n(('note:まとめ'))
1660
+
1661
+ * I'm working on the followings as a Rubyist\n
1662
+ (('note:Rubyistとしての私の活動'))
1663
+ * Increase what Ruby can\n
1664
+ (('note:Rubyでできることを増やす'))
1665
+ * Maintain libraries\n
1666
+ (('note:ライブラリーのメンテナス'))
1667
+ * Do you want to work with me?\n
1668
+ (('note:一緒にやりたい人はいる?'))