Rabbit Slide Show

Making Ruby? - ゆるふわRuby生活

2017-09-18

Description

Keynote at RubyKaigi 2017.

Text

Page: 1

Making Ruby?
ゆるふわRuby生活
Nobuyoshi Nakada / 中田伸悦
Salseforce.com / Heroku
Powered by Rabbit 2.2.2 and COZMIXNG

Page: 2

Self-introduction
Fulltime Ruby Committer @
Salesforce.com / Heroku
(2011~)
So called Matz team
Matz
Nobu
Ko1

Page: 3

日常/Daily
デバッグ/Debugging
新機能/New features
バグ/Bug making
家事・育児/Housekeeping etc

Page: 4

About Ruby development
Repository
Issues
Developers’ meeting

Page: 5

Repository
Subversion
svn+ssh://svn@ci.ruby-lang.org/ruby
https://svn.ruby-lang.org/cgi-bin/viewvc.cgi/
Git mirror
https://github.com/ruby/ruby

Page: 6

Why not Git?
ruby is older than Git
moving to git needs some works
hash is not clear as revision
number
Windows is not supported
officially
Not enough advantage

Page: 7

Issues
Redmine
https://bugs.ruby-lang.org/projects/ruby-trunk/issues
Mailing List
ruby-core@ruby-lang.org (en)
ruby-dev@ruby-lang.org (ja)

Page: 8

Developers’ meeting
Once per month
In Tokyo (usually)
in Kyoto 2016/9
Taking inventory of bug tickets

Page: 9

How to build Ruby (from tarball)
Similar to other OSS
configure
+
make

Page: 10

Out-of-Place build
Various configure options
Virtual machines
Linux, Windows, …
GNU Makefile to build at once
https://github.com/nobu/build-files/blob/master/Ruby.mk

Page: 11

Various configure options
Many build directories by combination
--enable-shared
--with-arch
optflags
etc

Page: 12

How to Build Ruby
(from repo)
subversion / git(mirror)
autoconf
bison
gperf
ruby

Page: 13

To build Ruby, you need Ruby

Page: 14

Ruby
BASERUBY
pre-installed ruby
MINIRUBY
ruby made during the build

Page: 15

BASERUBY
Ruby (maybe old) to generate source
files
parse.y → parse.c, …
defs/id.def → id.h, id.c
insns.def → vm.inc, insns.inc,
…
etc…

Page: 16

MINIRUBY
To generate Makefiles for extension
libraries, and others

Page: 17

MINIRUBY’s feature
No dynamic loading
↓
Runnable alone
No LD_LIBRARY_PATH
Convenient for debugging

Page: 18

MINIRUBY’s limitation
Feature can be also a limitation
Unable to load extension
libraries
b/c restriction of Windows DLL
can’t share exts with normal ruby
built-in encodings only
ASCII-8BIT, US-ASCII, UTF-8
for -K option: EUC-JP, Shift_JIS

Page: 19

Building encodings
To generate Makefile by erb
no details
Similar to exts but bit simpler

Page: 20

Building extension libraries
execute extconf.rb files under
ext and gems directories
Dir.glob("{ext,gems}/**/extconf.rb") do |file|
load(file)
end
generate dedicated Makefile
(exts.mk)

Page: 21

Parallel build (~2.4)
building miniruby ⇒ parallel
(w/ GNU make)
building extension libraries ⇒
parallel
each extconf.rb ⇒ sequential
⇒ making exts.mk is slow

Page: 22

Parallel build (2.5)
run each directories underneath
ext and gems
no dependencies each other
depends on the parent only
composite each exts.mk files
⇒ faster configuration

Page: 23

Problem
No headers and libraries are
installed at build
C headers provided by ruby
ruby.h, etc
library files provided by ruby
libruby.so, etc

Page: 24

Solution
Mimic global variables used in
mkmf.rb by trace_var
$extmk
$ruby

Page: 25

trace_var
Hook changes of a global variable
trace_var(symbol, cmd )
trace_var(symbol) {|val| block }
-> nil
-> nil
Controls tracing of assignments to global variables. The parameter symbol
identifies the variable (as either a string name or a symbol identifier).
cmd (which may be a string or a Proc object) or block is executed
whenever the variable is assigned. The block or Proc object receives the
variable's new value as a parameter. Also see Kernel::untrace_var.
trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
$_ = "hello"
$_ = ' there'
produces:
$_ is now 'hello'
$_ is now ' there'

Page: 26

$extmk
Flag to handle bundled exts in mkmf.rb
set source directory from build
directory
set built extension directory
chain $ruby hook

Page: 27

$ruby
Path to ruby to run
set up RbConfig configurations
set $ruby path

Page: 28

?

Page: 29

Bug Report
[ruby-list:50578]

Page: 30

w/o local variable
# p = 2
p (-1.3).abs #=> 1.3

Page: 31

w/ local variable
p = 2
p (-1.3).abs #=> -1.3

Page: 32

Exactly Not-A-Bug
Ancient Spec
at least 1.1

Page: 33

Just-size bug
“Demon Castle parse.y” by mame
“Monstrous” lex_state
But not so hard

Page: 34

NOT SO
HARD?

Page: 35

-w option
$ ruby -w -e 'p=2; p (-1.3).abs'
-e:1: warning: don't put space
before argument parentheses

Page: 36

parser_yylex()
the lexical analysis
case '(':
// ...
else if (lex_state == (EXPR_END|EXPR_LABEL) && space_seen) {
rb_warning0("don't put space before argument parentheses");
}
// ...
SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);

Page: 37

What’s space_seen?
a space was seen just before the
current token?
p (-1.3).abs
^------------!Here!

Page: 38

lex_state
state of lexer
(EXPR_END|EXPR_LABEL) …

Page: 39

What’s EXPR_END?
Able to end an expression
just after right paren of method
just after method name w/o paren
just after method arg w/o paren
…

Page: 40

What’s EXPR_LABEL?
Able to place a label
just after left paren of method
just after method name w/o paren
just after method arg w/o paren

Page: 41

In parse_ident()
parse an identifier starts with a
lower letter (local variable / method)
ident = tokenize_ident(parser, last_state);
if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
(result == tIDENTIFIER) && /* not EXPR_FNAME, not attrasgn */
lvar_defined(ident)) {
SET_LEX_STATE(EXPR_END|EXPR_LABEL);
}

Page: 42

What’s lvar_defined(ident)?
Prediction to tell “whether the name
referred as ident (p here) is
defined as a local variable in the
current scope”

Page: 43

Rules
W/o variable
primary
: tLPAREN_ARG
W/ variable
paren_args
: '(' opt_call_args rparen

Page: 44

How to Fix?
Remove the condition by lvar_defined
I consider it a bug, but…

Page: 45

?

Page: 46

literal symbol by intern
compile.c (iseq_compile_each0):
literal symbol should not be
affected by redefinition of
String#intern method.
vm_insnhelper.c (rb_vm_str_intern):
intern a string into a
symbol directly.

Page: 47

literal symbol by intern
:"#{foo}"

Page: 48

[Feature #13812]
Refinements can’t affect string
interpolation

Page: 49

Difference
Conversion is explicitly visible or
not

Page: 50

New Features
No eye-catcher in 2.5
Such as &. in 2.3
“Unicode case” in 2.4

Page: 51

Approved
rescue inside do/end
Array#append, prepend
Hash#transform_keys
Kernel#yield_self
…

Page: 52

Rejected
neko ^..^ operator (in Perl6)
User-defined operator

Page: 53

Under Discussion
Method extraction operator
Kernel#method -> Method instance
Rightward assignment

Page: 54

Write Ruby
Wouldn’t you write New Ruby?
Powered by Rabbit 2.2.2 and COZMIXNG

Other slides