rabbit-slide-shugo-RubyKaigi2018 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.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/Build your own tools.pdf +0 -0
- data/README.md +5 -0
- data/Rakefile +17 -0
- data/bicycle.jpg +0 -0
- data/broken_pin_header.jpg +0 -0
- data/broken_pin_header_orig.jpg +0 -0
- data/build-your-own-tools.md +636 -0
- data/config.yaml +19 -0
- data/keyboard.jpg +0 -0
- data/pdf/RubyKaigi2018-build-your-own-tools.pdf +0 -0
- data/rroonga.png +0 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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
|
data/bicycle.jpg
ADDED
Binary file
|
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
|
+
{: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
|
+
{: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
|
+
{: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
|
data/config.yaml
ADDED
@@ -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:
|
data/keyboard.jpg
ADDED
Binary file
|
Binary file
|
data/rroonga.png
ADDED
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: []
|