rabbit-slide-nobu-rubykaigi-2017 2017.9.18.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/2017-keynote.md +463 -0
- data/9363/9363.png +0 -0
- data/README.md +4 -0
- data/Rakefile +17 -0
- data/config.yaml +21 -0
- data/pdf/rubykaigi-2017-keynote.pdf +0 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ba57a94d6bef3833a43b6d5cd4f63ce7347004d
|
4
|
+
data.tar.gz: 654349ceacb47177f14768b02162096dd9ef8b13
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a9fceafc1950591c68cc20e033d28709ae654024c85d6929c95a3c89b4d63648a113b9f437872a9ae45206cef5cca7f292ba7122c24e36e0983771192b2b5409
|
7
|
+
data.tar.gz: 4ead9c9361c6d241b84a1a497eaaa0d29065285c1698d3aa16fc398633a2dea211042c32eab3d856f5ce87fa8f28fb51a586804c59ed9b275bcfb59eadd2391f
|
data/.rabbit
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2017-keynote.md
|
data/2017-keynote.md
ADDED
@@ -0,0 +1,463 @@
|
|
1
|
+
# Making Ruby?
|
2
|
+
|
3
|
+
subtitle
|
4
|
+
: ゆるふわRuby生活
|
5
|
+
|
6
|
+
author
|
7
|
+
: Nobuyoshi Nakada / 中田伸悦
|
8
|
+
|
9
|
+
institution
|
10
|
+
: Salseforce.com / Heroku
|
11
|
+
|
12
|
+
theme
|
13
|
+
: lightning-rabbit
|
14
|
+
|
15
|
+
allotted-time
|
16
|
+
: 60m
|
17
|
+
|
18
|
+
# Self-introduction
|
19
|
+
|
20
|
+
{:.center}
|
21
|
+
Fulltime Ruby Committer @ Salesforce.com / Heroku
|
22
|
+
{::note}(2011~){:/note}
|
23
|
+
|
24
|
+
So called Matz team
|
25
|
+
|
26
|
+
* Matz
|
27
|
+
* Nobu
|
28
|
+
* {::wait/}~~Ko1~~
|
29
|
+
|
30
|
+
# 日常/Daily
|
31
|
+
|
32
|
+
* {::wait/}デバッグ/Debugging
|
33
|
+
* {::wait/}新機能/New features
|
34
|
+
* {::wait/}バグ/Bug making
|
35
|
+
* {::wait/}家事・育児/Housekeeping etc
|
36
|
+
|
37
|
+
# About Ruby development
|
38
|
+
|
39
|
+
* Repository
|
40
|
+
|
41
|
+
* Issues
|
42
|
+
|
43
|
+
* Developers' meeting
|
44
|
+
|
45
|
+
# Repository
|
46
|
+
|
47
|
+
* Subversion
|
48
|
+
{::note} svn+ssh://svn@ci.ruby-lang.org/ruby{:/note}
|
49
|
+
{::note} https://svn.ruby-lang.org/cgi-bin/viewvc.cgi/{:/note}
|
50
|
+
|
51
|
+
* Git mirror
|
52
|
+
{::note} https://github.com/ruby/ruby {:/note}
|
53
|
+
|
54
|
+
# Why not Git?
|
55
|
+
|
56
|
+
* ruby is older than Git
|
57
|
+
* moving to git needs some works
|
58
|
+
* hash is not clear as revision number
|
59
|
+
* Windows is not supported *officially*
|
60
|
+
|
61
|
+
Not enough advantage
|
62
|
+
|
63
|
+
# Issues
|
64
|
+
|
65
|
+
* Redmine
|
66
|
+
{::note} https://bugs.ruby-lang.org/projects/ruby-trunk/issues {:/note}
|
67
|
+
|
68
|
+
* Mailing List
|
69
|
+
* ruby-core@ruby-lang.org (en)
|
70
|
+
* ruby-dev@ruby-lang.org (ja)
|
71
|
+
|
72
|
+
# Developers' meeting
|
73
|
+
|
74
|
+
* Once per month
|
75
|
+
|
76
|
+
* In Tokyo (usually)
|
77
|
+
{::note}in Kyoto 2016/9{:/note}
|
78
|
+
|
79
|
+
* Taking inventory of bug tickets
|
80
|
+
|
81
|
+
# How to build Ruby (from tarball)
|
82
|
+
|
83
|
+
{:.center}
|
84
|
+
Similar to other OSS
|
85
|
+
|
86
|
+
```
|
87
|
+
configure
|
88
|
+
```
|
89
|
+
|
90
|
+
{:.center}
|
91
|
+
+
|
92
|
+
|
93
|
+
```
|
94
|
+
make
|
95
|
+
```
|
96
|
+
|
97
|
+
# Out-of-Place build
|
98
|
+
|
99
|
+
* Various `configure` options
|
100
|
+
* Virtual machines
|
101
|
+
{::note}Linux, Windows, ...{:/note}
|
102
|
+
* GNU Makefile to build at once
|
103
|
+
{::note}https://github.com/nobu/build-files/blob/master/Ruby.mk{:/note}
|
104
|
+
|
105
|
+
# Various `configure` options
|
106
|
+
|
107
|
+
Many build directories by combination
|
108
|
+
|
109
|
+
* `--enable-shared`
|
110
|
+
* `--with-arch`
|
111
|
+
* `optflags`
|
112
|
+
* etc
|
113
|
+
|
114
|
+
# How to Build Ruby {::note}(from repo){:/note}
|
115
|
+
|
116
|
+
* {::wait/}subversion / git(mirror)
|
117
|
+
* {::wait/}autoconf
|
118
|
+
* {::wait/}bison
|
119
|
+
* {::wait/}gperf
|
120
|
+
* {::wait/}ruby
|
121
|
+
|
122
|
+
# To build Ruby, you need _Ruby_
|
123
|
+
|
124
|
+
{:relative_height='80'}
|
125
|
+
|
126
|
+
|
127
|
+
# Ruby
|
128
|
+
|
129
|
+
* BASERUBY
|
130
|
+
|
131
|
+
pre-installed ruby
|
132
|
+
|
133
|
+
* MINIRUBY
|
134
|
+
|
135
|
+
ruby made during the build
|
136
|
+
|
137
|
+
# BASERUBY
|
138
|
+
|
139
|
+
Ruby (maybe old) to generate source files
|
140
|
+
|
141
|
+
* parse.y → parse.c, ...
|
142
|
+
* defs/id.def → id.h, id.c
|
143
|
+
* insns.def → vm.inc, insns.inc, ...
|
144
|
+
* etc...
|
145
|
+
|
146
|
+
# MINIRUBY
|
147
|
+
|
148
|
+
To generate Makefiles for extension libraries, and others
|
149
|
+
|
150
|
+
# MINIRUBY's feature
|
151
|
+
|
152
|
+
{:.center}
|
153
|
+
No dynamic loading
|
154
|
+
↓
|
155
|
+
Runnable alone
|
156
|
+
|
157
|
+
* No `LD_LIBRARY_PATH`
|
158
|
+
* Convenient for debugging
|
159
|
+
|
160
|
+
# MINIRUBY's limitation
|
161
|
+
|
162
|
+
{:.center}
|
163
|
+
Feature can be also a limitation
|
164
|
+
|
165
|
+
* Unable to load extension libraries
|
166
|
+
|
167
|
+
* b/c restriction of Windows DLL
|
168
|
+
* can't share exts with normal ruby
|
169
|
+
|
170
|
+
* built-in encodings only
|
171
|
+
|
172
|
+
* ASCII-8BIT, US-ASCII, UTF-8
|
173
|
+
* for -K option: EUC-JP, Shift_JIS
|
174
|
+
|
175
|
+
# Building encodings
|
176
|
+
|
177
|
+
To generate Makefile by erb
|
178
|
+
|
179
|
+
{::note}no details{:/note}
|
180
|
+
|
181
|
+
Similar to exts but bit simpler
|
182
|
+
|
183
|
+
# Building extension libraries
|
184
|
+
|
185
|
+
* execute extconf.rb files under `ext` and `gems` directories
|
186
|
+
|
187
|
+
``` ruby
|
188
|
+
Dir.glob("{ext,gems}/**/extconf.rb") do |file|
|
189
|
+
load(file)
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
* generate dedicated Makefile (exts.mk)
|
194
|
+
|
195
|
+
# Parallel build (~2.4)
|
196
|
+
|
197
|
+
* building miniruby ⇒ parallel
|
198
|
+
{::note}(w/ GNU make){:/note}
|
199
|
+
|
200
|
+
* building extension libraries ⇒ parallel
|
201
|
+
|
202
|
+
* each extconf.rb ⇒ sequential
|
203
|
+
|
204
|
+
* {::wait/}⇒ making exts.mk is slow
|
205
|
+
|
206
|
+
# Parallel build (2.5)
|
207
|
+
|
208
|
+
* run each directories underneath `ext` and `gems`
|
209
|
+
|
210
|
+
* no dependencies each other
|
211
|
+
* depends on the parent only
|
212
|
+
|
213
|
+
* composite each exts.mk files
|
214
|
+
|
215
|
+
* {::wait/}⇒ faster configuration
|
216
|
+
|
217
|
+
# Problem
|
218
|
+
|
219
|
+
No headers and libraries are installed at build
|
220
|
+
|
221
|
+
* C headers provided by ruby
|
222
|
+
ruby.h, etc
|
223
|
+
|
224
|
+
* library files provided by ruby
|
225
|
+
libruby.so, etc
|
226
|
+
|
227
|
+
# Solution
|
228
|
+
|
229
|
+
Mimic global variables used in mkmf.rb by __`trace_var`__
|
230
|
+
|
231
|
+
* `$extmk`
|
232
|
+
* `$ruby`
|
233
|
+
|
234
|
+
# trace_var
|
235
|
+
|
236
|
+
Hook changes of a global variable
|
237
|
+
|
238
|
+
```
|
239
|
+
trace_var(symbol, cmd ) -> nil
|
240
|
+
trace_var(symbol) {|val| block } -> nil
|
241
|
+
|
242
|
+
Controls tracing of assignments to global variables. The parameter symbol
|
243
|
+
identifies the variable (as either a string name or a symbol identifier).
|
244
|
+
cmd (which may be a string or a Proc object) or block is executed
|
245
|
+
whenever the variable is assigned. The block or Proc object receives the
|
246
|
+
variable's new value as a parameter. Also see Kernel::untrace_var.
|
247
|
+
|
248
|
+
trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
|
249
|
+
$_ = "hello"
|
250
|
+
$_ = ' there'
|
251
|
+
|
252
|
+
produces:
|
253
|
+
|
254
|
+
$_ is now 'hello'
|
255
|
+
$_ is now ' there'
|
256
|
+
```
|
257
|
+
|
258
|
+
# `$extmk`
|
259
|
+
|
260
|
+
Flag to handle bundled exts in mkmf.rb
|
261
|
+
|
262
|
+
* set source directory from build directory
|
263
|
+
* set built extension directory
|
264
|
+
* chain `$ruby` hook
|
265
|
+
|
266
|
+
# `$ruby`
|
267
|
+
|
268
|
+
Path to `ruby` to run
|
269
|
+
|
270
|
+
* set up `RbConfig` configurations
|
271
|
+
* set `$ruby` path
|
272
|
+
|
273
|
+
# ?
|
274
|
+
|
275
|
+
# Bug Report
|
276
|
+
|
277
|
+
[ruby-list:50578]
|
278
|
+
|
279
|
+
# w/o local variable
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
# p = 2
|
283
|
+
p (-1.3).abs #=> 1.3
|
284
|
+
```
|
285
|
+
|
286
|
+
# w/ local variable
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
p = 2
|
290
|
+
p (-1.3).abs #=> -1.3
|
291
|
+
```
|
292
|
+
|
293
|
+
# Exactly Not-A-Bug
|
294
|
+
|
295
|
+
{:.center}
|
296
|
+
{::tag name="x-large"}__Ancient Spec__{:/tag}
|
297
|
+
at least 1.1
|
298
|
+
|
299
|
+
# Just-size bug
|
300
|
+
|
301
|
+
* "Demon Castle parse.y" by mame
|
302
|
+
|
303
|
+
* {::wait/}"Monstrous" `lex_state`
|
304
|
+
|
305
|
+
* {::wait/}But not so hard
|
306
|
+
|
307
|
+
# NOT SO HARD?
|
308
|
+
|
309
|
+
# `-w` option
|
310
|
+
|
311
|
+
```
|
312
|
+
$ ruby -w -e 'p=2; p (-1.3).abs'
|
313
|
+
-e:1: warning: don't put space
|
314
|
+
before argument parentheses
|
315
|
+
```
|
316
|
+
|
317
|
+
# `parser_yylex()`
|
318
|
+
|
319
|
+
the lexical analysis
|
320
|
+
|
321
|
+
```c
|
322
|
+
case '(':
|
323
|
+
// ...
|
324
|
+
else if (lex_state == (EXPR_END|EXPR_LABEL) && space_seen) {
|
325
|
+
rb_warning0("don't put space before argument parentheses");
|
326
|
+
}
|
327
|
+
// ...
|
328
|
+
SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
|
329
|
+
```
|
330
|
+
|
331
|
+
# What's `space_seen`?
|
332
|
+
|
333
|
+
a space was seen just before the current token?
|
334
|
+
|
335
|
+
``` ruby
|
336
|
+
p (-1.3).abs
|
337
|
+
^------------!Here!
|
338
|
+
```
|
339
|
+
|
340
|
+
# lex_state
|
341
|
+
|
342
|
+
state of lexer
|
343
|
+
|
344
|
+
`(EXPR_END|EXPR_LABEL)` ...
|
345
|
+
|
346
|
+
# What's `EXPR_END`?
|
347
|
+
|
348
|
+
Able to end an expression
|
349
|
+
|
350
|
+
* just after right paren of method
|
351
|
+
|
352
|
+
* just after method name w/o paren
|
353
|
+
|
354
|
+
* just after method arg w/o paren
|
355
|
+
|
356
|
+
* ...
|
357
|
+
|
358
|
+
# What's `EXPR_LABEL`?
|
359
|
+
|
360
|
+
Able to place a label
|
361
|
+
|
362
|
+
* just after left paren of method
|
363
|
+
|
364
|
+
* just after method name w/o paren
|
365
|
+
|
366
|
+
* just after method arg w/o paren
|
367
|
+
|
368
|
+
# In `parse_ident()`
|
369
|
+
|
370
|
+
parse an identifier starts with a lower letter (local variable / method)
|
371
|
+
|
372
|
+
``` c
|
373
|
+
ident = tokenize_ident(parser, last_state);
|
374
|
+
if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
|
375
|
+
(result == tIDENTIFIER) && /* not EXPR_FNAME, not attrasgn */
|
376
|
+
lvar_defined(ident)) {
|
377
|
+
SET_LEX_STATE(EXPR_END|EXPR_LABEL);
|
378
|
+
}
|
379
|
+
```
|
380
|
+
|
381
|
+
# What's `lvar_defined(ident)`?
|
382
|
+
|
383
|
+
Prediction to tell "whether the name referred as `ident` (`p` here) is
|
384
|
+
defined as a local variable in the current scope"
|
385
|
+
|
386
|
+
# Rules
|
387
|
+
|
388
|
+
W/o variable
|
389
|
+
|
390
|
+
```c
|
391
|
+
primary : tLPAREN_ARG
|
392
|
+
```
|
393
|
+
|
394
|
+
W/ variable
|
395
|
+
|
396
|
+
```c
|
397
|
+
paren_args : '(' opt_call_args rparen
|
398
|
+
```
|
399
|
+
|
400
|
+
# How to Fix?
|
401
|
+
|
402
|
+
Remove the condition by `lvar_defined`
|
403
|
+
|
404
|
+
{::wait/}_I_ consider it a bug, but...
|
405
|
+
|
406
|
+
# ?
|
407
|
+
|
408
|
+
# literal symbol by intern
|
409
|
+
|
410
|
+
* compile.c (`iseq_compile_each0`): literal symbol should not be
|
411
|
+
affected by redefinition of `String#intern` method.
|
412
|
+
|
413
|
+
* vm_insnhelper.c (`rb_vm_str_intern`): intern a string into a
|
414
|
+
symbol directly.
|
415
|
+
|
416
|
+
# literal symbol by intern
|
417
|
+
|
418
|
+
```ruby
|
419
|
+
:"#{foo}"
|
420
|
+
|
421
|
+
```
|
422
|
+
|
423
|
+
# [Feature #13812]
|
424
|
+
|
425
|
+
Refinements can't affect string interpolation
|
426
|
+
|
427
|
+
# Difference
|
428
|
+
|
429
|
+
Conversion is explicitly visible or not
|
430
|
+
|
431
|
+
# New Features
|
432
|
+
|
433
|
+
> No eye-catcher in 2.5
|
434
|
+
|
435
|
+
Such as `&.` in 2.3
|
436
|
+
|
437
|
+
"Unicode case" in 2.4
|
438
|
+
|
439
|
+
# Approved
|
440
|
+
|
441
|
+
* `rescue` inside `do`/`end`
|
442
|
+
* `Array`#`append`, `prepend`
|
443
|
+
* `Hash`#`transform_keys`
|
444
|
+
* `Kernel`#`yield_self`
|
445
|
+
* ...
|
446
|
+
|
447
|
+
# Rejected
|
448
|
+
|
449
|
+
* neko `^..^` operator (in Perl6)
|
450
|
+
|
451
|
+
* User-defined operator
|
452
|
+
|
453
|
+
# Under Discussion
|
454
|
+
|
455
|
+
* Method extraction operator
|
456
|
+
|
457
|
+
* `Kernel#method` -> `Method` instance
|
458
|
+
|
459
|
+
* Rightward assignment
|
460
|
+
|
461
|
+
# Write Ruby
|
462
|
+
|
463
|
+
Wouldn't you write __New Ruby__?
|
data/9363/9363.png
ADDED
Binary file
|
data/README.md
ADDED
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 += ["9363/9363.png"]
|
9
|
+
# spec.files -= Dir.glob("private/**/*.*")
|
10
|
+
# spec.add_runtime_dependency("rabbit-theme-clear-code")
|
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/config.yaml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
id: rubykaigi-2017
|
3
|
+
base_name: keynote
|
4
|
+
tags:
|
5
|
+
- rubykaigi
|
6
|
+
presentation_date: 2017-09-18
|
7
|
+
version: 2017.9.18.0
|
8
|
+
licenses:
|
9
|
+
- CC-BY-SA-4.0
|
10
|
+
slideshare_id:
|
11
|
+
speaker_deck_id:
|
12
|
+
ustream_id:
|
13
|
+
vimeo_id:
|
14
|
+
youtube_id:
|
15
|
+
author:
|
16
|
+
markup_language: :rd
|
17
|
+
name: Nobuyoshi Nakada
|
18
|
+
email: nobu@ruby-lang.org
|
19
|
+
rubygems_user: nobu
|
20
|
+
slideshare_user:
|
21
|
+
speaker_deck_user:
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-nobu-rubykaigi-2017
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2017.9.18.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nobuyoshi Nakada
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-09-20 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
|
+
description: Keynote at RubyKaigi 2017.
|
28
|
+
email:
|
29
|
+
- nobu@ruby-lang.org
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".rabbit"
|
35
|
+
- 2017-keynote.md
|
36
|
+
- 9363/9363.png
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- config.yaml
|
40
|
+
- pdf/rubykaigi-2017-keynote.pdf
|
41
|
+
homepage: http://slide.rabbit-shocker.org/authors/nobu/rubykaigi-2017/
|
42
|
+
licenses:
|
43
|
+
- CC-BY-SA-4.0
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 2.5.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: "= Making Ruby? - ゆるふわRuby生活"
|
65
|
+
test_files: []
|