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: 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: 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: 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