rabbit-slide-shugo-RubyKaigi2018 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 471c9a21d6853b9cd74dbb761511c0ecb786b91cfd3112a26d3b815edeeb6d24
4
+ data.tar.gz: 227e6121a4f563b15caaf6d1715494a0fe6cbdc74c5838135d4878475fa28609
5
+ SHA512:
6
+ metadata.gz: c6b843bf765b9c86892e8b190931f09048a3809b3ac31cee3bc81777d871b41066b783443215c6e4ed2b22631cacf449a72ad4ad41b41bbad30d16fd4a5426fa
7
+ data.tar.gz: bf9f08c726476fc8413ae532dd2cfd233225ecc01c2c63976e3b1a1d92a3d83255dfa0e72211b084f5682b52c3ae0f81eab608085b323f9c40eb99a502225873
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ build-your-own-tools.md
Binary file
@@ -0,0 +1,5 @@
1
+ # Build your own tools
2
+
3
+ Now FLOSS is so common that even Microsoft use it and develop it. But do you have control over your tools for daily use?
4
+
5
+ Building your own tools is the best way to develop software, and Ruby is the best language for such use. In this talk, I introduce my own tools and my development style.
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # spec.files += Dir.glob("doc/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ spec.add_runtime_dependency("rabbit-theme-lightning-night-black")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
Binary file
Binary file
@@ -0,0 +1,636 @@
1
+ # Build your own tools
2
+
3
+ author
4
+ : Shugo Maeda
5
+
6
+ institution
7
+ : Network Applied Communication Laboratory Ltd.
8
+
9
+ date
10
+ : 2018-06-02
11
+
12
+ theme
13
+ : lightning-night-black
14
+
15
+ allotted-time
16
+ : 40m
17
+
18
+ # Self introduction
19
+
20
+ * Shugo Maeda
21
+ * Ruby committer
22
+ * Secretary General at Ruby Association
23
+ * Director at Network Applied Communication Laboratory Ltd. (NaCl)
24
+
25
+ # Proposed features
26
+
27
+ * protected
28
+ * callcc
29
+ * Refinements
30
+ * puts
31
+
32
+ # Ruby Association
33
+
34
+ * Foundation dedicated to Ruby
35
+ * Maintenance of the stable version of Ruby
36
+ * Grant
37
+ * Conferences and Seminars
38
+ * Case studies at www.ruby.or.jp
39
+ * Examination
40
+
41
+ # [ANN] Grant report
42
+
43
+ * Date: 2018-07-07
44
+ * Venue: Shinagawa, Tokyo
45
+ * Speakers: Matz, Naotoshi Seo, Uchio Kondo, Takashi Kokubun
46
+ * https://rubyassociation.doorkeeper.jp/events/74355
47
+
48
+ # [ANN] RubyWorld Conference
49
+
50
+ * Date: 2018-11-01 〜 2018-11-02
51
+ * Venue: Matsue, Shimane
52
+ * Keynote Speakers: Matz, Chad Fowler
53
+ * http://www.rubyworld-conf.org
54
+
55
+ # NaCl
56
+
57
+ * Commissioned development of Web (and other) applications
58
+ * Foucused on FLOSS
59
+ * Matz belongs to NaCl since 1997
60
+ * Head office in Shimane / Branch office in Tokyo
61
+
62
+ # FLOSS
63
+
64
+ * Free/Libre and Open Source Software
65
+
66
+ # Free software
67
+
68
+ * ~~Free as in beer~~
69
+ * Free as in speech
70
+ * 自由ソフトウェア
71
+ * Social movement
72
+
73
+ # Open source software
74
+
75
+ * Open Source Definition
76
+ * Published by the Open Source Initiative
77
+ * Based on Debian Free Software Guidelines
78
+ * Development methodology
79
+
80
+ # Microsoft
81
+
82
+ * Joined the Linux Foundation
83
+ * https://www.linuxfoundation.org/press-release/microsoft-fortifies-commitment-to-open-source-becomes-linux-foundation-platinum-member/
84
+ * Joined the Open Source Initiative
85
+ * https://opensource.org/node/901
86
+
87
+ # Did FLOSS win?
88
+
89
+ # Web applications
90
+
91
+ * Everyone use them
92
+ * FLOSS used often
93
+ * Linux, GNU toolchain, Apache, Ruby, Rails...
94
+
95
+ # I hate Web applications
96
+
97
+ # I hate
98
+
99
+ * Gmail
100
+ * Google Docs, Sheets, and Slides
101
+ * Cloud9
102
+
103
+ # These are OK
104
+
105
+ * tDiary
106
+ * Redmine
107
+ * Amazon (shopping site)
108
+ * Netflix
109
+
110
+ # What is common to these?
111
+
112
+ # SaaSS
113
+
114
+ * ≠ SaaS (Software as a Service)
115
+ * *S*ervice *a*s *a* *S*oftware *S*ubstitute
116
+ * https://www.gnu.org/philosophy/who-does-that-server-really-serve.html
117
+ * Services for your computing
118
+
119
+ # Non SaaSS
120
+
121
+ * FLOSS
122
+ * tDiary
123
+ * Redmine
124
+ * Not for your computing
125
+ * Amazon
126
+ * Netflix
127
+
128
+ # Take back control over your computing
129
+
130
+ # Build your own tools
131
+
132
+ # Why?
133
+
134
+ * You can't always get what you want
135
+ * Serve yourself
136
+ * For fun
137
+
138
+ # Why Ruby?
139
+
140
+ * Availability
141
+ * Productivity
142
+ * Text handling power
143
+ * Ecosystem
144
+ * Fun
145
+
146
+ # My own tools
147
+
148
+ # Keyboard
149
+
150
+ ![](keyboard.jpg){:relative_height="100"}
151
+
152
+ # Viterbi
153
+
154
+ * Split Ortholinear keyboard kit
155
+ * Available at https://keeb.io
156
+
157
+ # Hard to fix hardware
158
+
159
+ ![](broken_pin_header.jpg){:relative_height="100"}
160
+
161
+ # Free keyboard
162
+
163
+ # QMK Firmware
164
+
165
+ * Open source firmware for AVR and ARM based keyboards
166
+ * Lincensed under GPL
167
+
168
+ # T-Code Keyboard
169
+
170
+ * T-Code
171
+ * Direct Kanji Input
172
+ * No Kana-to-Kanji conversion
173
+ * Kanji composition
174
+ * e.g. 五 + 口 = 吾
175
+ * Implemented on QMK Firmware
176
+
177
+ # No Ruby Inside
178
+
179
+ * Max firmware size: 28KB
180
+ * Even mruby/c is too large
181
+ * Written in C
182
+ * http://nacl-ltd.github.io/2018/01/23/japanese-input-by-qmk.html
183
+
184
+ # Table generation
185
+
186
+ ```ruby
187
+ require_relative "tc_tbl"
188
+
189
+ puts "/* Generated by gentbl.rb; DO NOT EDIT! */"
190
+ puts "const uint16_t PROGMEM tcode_table[] = {\n"
191
+ TC_TBL.flat_map { |row|
192
+ row.gsub(" ", "").each_char.map { |ch|
193
+ "0x%04X" % ch.ord
194
+ }
195
+ }.each_slice(8) do |cs|
196
+ puts " " + cs.join(", ") + ","
197
+ end
198
+ puts "};\n"
199
+ ```
200
+
201
+ # Generated table
202
+
203
+ ```ruby
204
+ * Generated by gentbl.rb; DO NOT EDIT! */
205
+ const uint16_t PROGMEM tcode_table[] = {
206
+ 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0,
207
+ 0x25A0, 0x25A0, 0x30EE, 0x30F0, 0x30F1, 0x30F5, 0x30F6, 0x8ACB,
208
+ 0x5883, 0x7CFB, 0x63A2, 0x8C61, 0x308E, 0x3090, 0x3091, 0x25A0,
209
+ 0x25A0, 0x76DB, 0x9769, 0x7A81, 0x6E29, 0x6355, 0x25A0, 0x25A0,
210
+ 0x25A0, 0x25A0, 0x25A0, 0x4F9D, 0x7E4A, 0x501F, 0x9808, 0x8A33,
211
+ 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0,
212
+ 0x25A0, 0x25A0, 0x4E11, 0x81FC, 0x5BB4, 0x7E01, 0x66F3, 0x5C1A,
213
+ 0x8CC0, 0x5CB8, 0x8CAC, 0x6F01, 0x65BC, 0x6C5A, 0x4E59, 0x7A4F,
214
+ 0x25A0, 0x76CA, 0x63F4, 0x5468, 0x57DF, 0x8352, 0x25A0, 0x25A0,
215
+ 0x25A0, 0x25A0, 0x25A0, 0x7E54, 0x7236, 0x679A, 0x4E71, 0x9999,
216
+ 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0,
217
+ 0x25A0, 0x25A0, 0x9B3C, 0x865A, 0x72ED, 0x8105, 0x9A5A, 0x820E,
218
+ 0x559C, 0x5E79, 0x4E18, 0x7CD6, 0x5947, 0x65E2, 0x83CA, 0x5374,
219
+ 0x4EAB, 0x5EB7, 0x5F92, 0x666F, 0x51E6, 0x305C, 0x25A0, 0x25A0,
220
+ 0x25A0, 0x25A0, 0x25A0, 0x8B72, 0x30D8, 0x6A21, 0x964D, 0x8D70,
221
+ 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0, 0x25A0,
222
+ ```
223
+
224
+ # Small scripts
225
+
226
+ # ftpup
227
+
228
+ * Upload files via FTP
229
+ * FTP was used to upload HTML files in the past
230
+ * Using Net::FTP
231
+
232
+ # imaparchive
233
+
234
+ * Move or Delete old mails on IMAP servers
235
+ * Using Net::IMAP
236
+
237
+ # rd2sxi
238
+
239
+ * Convert RD to OpenOffice Impress slides
240
+
241
+ # rd2latex
242
+
243
+ * Convert RD to LaTeX files
244
+
245
+ # Programming languages
246
+
247
+ # demi
248
+
249
+ * Original language for JVM
250
+ * Lisp-1
251
+ * No class definition
252
+ * `for` expression
253
+ * Closures
254
+ * REPL (*R*ead-*E*val-*P*rint *L*oop)
255
+
256
+ # Example
257
+
258
+ ```
259
+ frame = new Frame("Test");
260
+ frame.setLayout(new FlowLayout());
261
+ hello = new Button("Hello");
262
+ hello.addActionListener([ e:
263
+ println("Hello, World!");
264
+ ]);
265
+ frame.add(hello);
266
+ ```
267
+
268
+ # babel
269
+
270
+ * Sather Compiler for .NET
271
+ * Not a JavaScript compiler
272
+
273
+ # Sather
274
+
275
+ * Statically typed object oriented language
276
+ * Separation of Subtyping and Code Inclusion
277
+ * Iterators
278
+ * Closures
279
+
280
+ # Example
281
+
282
+ ```
283
+ abstract class $PERSON is
284
+ say;
285
+ end;
286
+
287
+ class HELLO_MIXIN is
288
+ say is
289
+ #OUT + "hello.\n";
290
+ end
291
+ end;
292
+
293
+ class PERSON < $PERSON is
294
+ include HELLO_MIXIN;
295
+ end
296
+ ```
297
+
298
+ # Servers
299
+
300
+ # rskkserv
301
+
302
+ * Dictionary server for SKK
303
+ * SKK: Japanese Input Method
304
+ * Binary search
305
+
306
+ # ximapd
307
+
308
+ * eXperimental IMAP server
309
+ * Use mailbox names as search queries
310
+
311
+ # TUI applications
312
+
313
+ # TUI
314
+
315
+ * *T*ext-based *U*ser *I*nterface
316
+ * Used on terminals
317
+ * More rich than CUI
318
+
319
+ # Textbringer
320
+
321
+ * Emacs-like text editor
322
+ * Less parentheses
323
+ * Matz Lisp a.k.a. Ruby
324
+ * Cool name
325
+
326
+ # Mournmail
327
+
328
+ * MUA (*M*essage *U*ser *A*gent)
329
+ * Textbringer plugin
330
+ * Gmail like search interface
331
+ * Powered by Groonga/Rroonga
332
+ * Multi account support
333
+ * Unstable specification
334
+
335
+ # Groonga/Rroonga
336
+
337
+ * Groonga
338
+ * Full-text search engine
339
+ * Rroonga
340
+ * Ruby interface for Groonga
341
+
342
+ # Good support
343
+
344
+ ![](rroonga.png){:relative_height="100"}
345
+
346
+ # Search multiple columns
347
+
348
+ ```ruby
349
+ # query = "jemalloc"
350
+ # query = "from:@matz subject:@ruby"
351
+ messages = Groonga["Messages"].select { |record|
352
+ record.match(query) { |match_record|
353
+ match_record.subject | match_record.body
354
+ }
355
+ }.paginate([["date", :desc]], page: page, size: 100)
356
+ ```
357
+
358
+ # Demo
359
+
360
+ # How to build tools
361
+
362
+ # Materials
363
+
364
+ * Motivation
365
+ * Time
366
+ * Skills
367
+
368
+ # Feel good about yourself
369
+
370
+ * Many geniuses in the world
371
+ * I'm not...
372
+ * But it's OK
373
+
374
+ # Find your favorite theme
375
+
376
+ * Text editors?
377
+ * Programming languages?
378
+ * Graphical tools?
379
+ * Machine learning?
380
+
381
+ # Start with something easy
382
+
383
+ * One liners
384
+ * Small scripts
385
+
386
+ # Examples
387
+
388
+ * Mail archivers over Message user agents
389
+ * Slide generators over Presentation tools
390
+
391
+ # Phisical LOC
392
+
393
+ |imaparchive| 99|
394
+ |ftpup | 294|
395
+ |rskkserv | 316|
396
+ |Mournmail | 2236|
397
+ |ximapd | 5101|
398
+ |Textbringer| 6526|
399
+ |babel | 11822|
400
+ |demi | 12205|
401
+
402
+ * exluding test code
403
+
404
+ # Cut corners
405
+
406
+ * Create a Minimum Viable Product before getting bored
407
+ * Reinvent the wheel only when you want to
408
+ * Inconvenience vs Implementation cost
409
+
410
+ # Examples in programming languages
411
+
412
+ * Use existing virtual machines
413
+ * Use existing libraries
414
+
415
+ # Examples in text editors
416
+
417
+ * ASCII support only at first
418
+ * Text User Interface
419
+ * Redisplay by curses
420
+
421
+ # Postpone test writing
422
+
423
+ * You don't know what you want at first
424
+ * Use it everyday instead
425
+ * Test code should help changes
426
+
427
+ # Specification bugs
428
+
429
+ * What's wrong in the following code?
430
+
431
+ ```ruby
432
+ def move_mail(src_mailbox, uid, dst_mailbox)
433
+ src_path = Mournmail.mail_cache_path(src_mailbox, uid)
434
+ dst_path = Mournmail.mail_cache_path(dst_mailbox, uid)
435
+ begin
436
+ File.rename(src_path, dst_path)
437
+ rescue Errno::ENOENT
438
+ end
439
+ ```
440
+
441
+ # UID is mailbox local
442
+
443
+ * UID is changed after COPY
444
+ * Change cache paths
445
+ * Old: mailbox/uid
446
+ * New: 00-ff/hash
447
+
448
+ # Take risks
449
+
450
+ * eval
451
+ * monkey patching
452
+ * refinements
453
+ * callcc
454
+
455
+ # Protect your data
456
+
457
+ * Leave mails on the IMAP server
458
+ * Dump unsaved files on crash
459
+ * Backup / Use VCS for important data
460
+
461
+ # Make it extensible
462
+
463
+ * Small core with extensions
464
+ * Emacs = *E*ditor *MAC*ro*S*
465
+
466
+ # Emacs vs vi
467
+
468
+ * Key bindings don't matter
469
+ * Extensible or not?
470
+ * Vim is an Emacs-type editor
471
+
472
+ # Extension languages
473
+
474
+ ||Host language|Extension language|
475
+ |----|----|----|
476
+ |GNU Emacs|C|Emacs Lisp|
477
+ |Vim|C|Vim script|
478
+ |Textbringer|Ruby|Ruby|
479
+
480
+ # Ruby
481
+
482
+ * Suitable for extensions
483
+ * Dynamic
484
+ * Brief notation
485
+
486
+ # Customization
487
+
488
+ ```ruby
489
+ def load_user_config
490
+ config_file = File.expand_path("~/.textbringer.rb")
491
+ begin
492
+ load(config_file)
493
+ rescue LoadError
494
+ end
495
+ end
496
+ ```
497
+
498
+ # ~/.textbringer.rb
499
+
500
+ ```ruby
501
+ CONFIG[:east_asian_ambiguous_width] = 2
502
+ Buffer.detect_encoding_proc = Buffer::NKF_DETECT_ENCODING
503
+
504
+ Face.define :mode_line, foreground: "#ffffff", background: "#75507b"
505
+
506
+ add_hook :c_mode_hook, -> {
507
+ buf = Buffer.current
508
+ if buf.file_name &&
509
+ File.dirname(buf.file_name).end_with?("/ruby")
510
+ buf[:indent_level] = 4
511
+ buf[:tab_width] = 8
512
+ buf[:indent_tabs_mode] = true
513
+ buf[:c_continued_statement_offset] = 4
514
+ buf[:c_case_label_offset] = -2
515
+ buf[:c_label_offset] = -2
516
+ end
517
+ }
518
+ ```
519
+
520
+ # Plugins
521
+
522
+ * Load files in ~/.textbringer/plugins
523
+ * Packaging system
524
+ * RubyGems
525
+
526
+ # Gem.find_latest_files
527
+
528
+ ```ruby
529
+ def self.load_plugins
530
+ files = Gem.find_latest_files("textbringer_plugin.rb", false) +
531
+ Dir.glob(File.join(directory, "*/**/textbringer_plugin.rb"))
532
+ files.each do |file|
533
+ begin
534
+ load(file)
535
+ rescue Exception => e
536
+ show_exception(e)
537
+ end
538
+ end
539
+ end
540
+ ```
541
+
542
+ # Interactive programming
543
+
544
+ * Change behavior of object at runtime
545
+ * load, eval, open classes
546
+ * REPL
547
+ * Examples in Textbringer
548
+ * eval_buffer, eval_region, eval_expression
549
+
550
+ # Unreloadable code
551
+
552
+ ```ruby
553
+ module Mournmail
554
+ @current_mailbox = nil
555
+ ```
556
+
557
+ # Keep states on reload
558
+
559
+ ```ruby
560
+ module Mournmail
561
+ def self.define_variable(name, initial_value: nil,
562
+ attr: nil)
563
+ var_name = "@" + name.to_s
564
+ if !instance_variable_defined?(var_name)
565
+ instance_variable_set(var_name, initial_value)
566
+ end
567
+ ...
568
+ end
569
+
570
+ define_variable :current_mailbox, attr: :accessor
571
+ ```
572
+
573
+ # Local monkey patching
574
+
575
+ ```ruby
576
+ module FillExtension
577
+ refine Buffer do
578
+ def fill_region(s, e)
579
+ ...
580
+ end
581
+ end
582
+ end
583
+
584
+ module Commands
585
+ using FillExtension
586
+ define_command(:fill_region) do
587
+ |s = Buffer.current.point, e = Buffer.current.mark|
588
+ Buffer.current.fill_region(s, e)
589
+ end
590
+ end
591
+ ```
592
+
593
+ # Internal DSLs
594
+
595
+ * Declarative
596
+ * Too much DSLs decrease readability as *Ruby code*
597
+
598
+ # Parser combinator
599
+
600
+ ```ruby
601
+ using RaddDjur::DSL
602
+
603
+ grammar = RaddDjur::Grammar.new(:additive) {
604
+ # additive ← multitive '+' additive / multitive
605
+ define :additive do
606
+ :multitive.bind { |x|
607
+ "+".bind {
608
+ :additive.bind { |y|
609
+ ret x + y
610
+ }
611
+ }
612
+ } / :multitive
613
+ end
614
+ ```
615
+
616
+ # Bootstrapping
617
+
618
+ * Self-compiling compiler
619
+ * C → Language X → Language X
620
+ * Self-editing text editor
621
+ * Vim → Textbringer → Textbringer
622
+
623
+ # After finished
624
+
625
+ # Osusowake
626
+
627
+ * Japanese word meaning sharing
628
+ * Share meals when cooked too much
629
+ * Software never decrease
630
+ * Share your software as FLOSS
631
+
632
+ # Summary
633
+
634
+ * Take back control over your computing
635
+ * Build your own tools by Ruby
636
+ * Share your tools as FLOSS
@@ -0,0 +1,19 @@
1
+ ---
2
+ id: RubyKaigi2018
3
+ base_name: build-your-own-tools
4
+ tags: []
5
+ presentation_date:
6
+ version: 1.0.0
7
+ licenses: []
8
+ slideshare_id:
9
+ speaker_deck_id:
10
+ ustream_id:
11
+ vimeo_id:
12
+ youtube_id:
13
+ author:
14
+ markup_language: :markdown
15
+ name: Shugo Maeda
16
+ email: shugo@ruby-lang.org
17
+ rubygems_user: shugo
18
+ slideshare_user: ShugoMaeda
19
+ speaker_deck_user:
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-shugo-RubyKaigi2018
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Shugo Maeda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-06-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rabbit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rabbit-theme-lightning-night-black
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |
42
+ Now FLOSS is so common that even Microsoft use it and develop it. But do you have control over your tools for daily use?
43
+
44
+ Building your own tools is the best way to develop software, and Ruby is the best language for such use. In this talk, I introduce my own tools and my development style.
45
+ email:
46
+ - shugo@ruby-lang.org
47
+ executables: []
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".rabbit"
52
+ - Build your own tools.pdf
53
+ - README.md
54
+ - Rakefile
55
+ - bicycle.jpg
56
+ - broken_pin_header.jpg
57
+ - broken_pin_header_orig.jpg
58
+ - build-your-own-tools.md
59
+ - config.yaml
60
+ - keyboard.jpg
61
+ - pdf/RubyKaigi2018-build-your-own-tools.pdf
62
+ - rroonga.png
63
+ homepage: http://slide.rabbit-shocker.org/authors/shugo/RubyKaigi2018/
64
+ licenses: []
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 3.0.0.beta1
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Build your own tools
86
+ test_files: []