Slide 1

Slide 1 text

The Journey of Box Building Satoshi Tagomori (@tagomoris) 2026-04-22, RubyKaigi 2026 Opening Keynote

Slide 2

Slide 2 text

ా᝷ ૱ (Satoshi Tagomori) @tagomoris SAKURA internet (2024.08ʙ) Cloud Business Strategy Division Maintainer/Founder: OSS: Ruby, Fluentd, MessagePack, 
 Norikra, Woothee, …
 Event: ISUCON Service: Pathtraq

Slide 3

Slide 3 text

https://www. fl ickr.com/photos/takkanm/3978417669 Asakusa.rb

Slide 4

Slide 4 text

Cloud Business Strategy Division, Deputy General Manager Represents Cloud Product

Slide 5

Slide 5 text

Ruby 4

Slide 6

Slide 6 text

ZJIT

Slide 7

Slide 7 text

Ruby Box

Slide 8

Slide 8 text

˒ What’s “Ruby Box”? ˒ Tour of Ruby Box ˒ Road to Box Building The Journey of Box Building

Slide 9

Slide 9 text

What’s Ruby Box?

Slide 10

Slide 10 text

˒ An experimental feature, introduced in Ruby 4.0 ˒ Renamed from “Namespace” after RubyKaigi 2025 ˒ Accessed as Ruby::Box ˒ Enabled by an ENV value RUBY_BOX=1 What’s “Ruby Box”?

Slide 11

Slide 11 text

˒ Separating apps/libs/monkey-patches into isolated spaces ˒ Load apps/libs in a space ˒ Hide changes of apps/libs in the space from other spaces ˒ Run methods de fi ned in the space with the de fi nitions Ruby Box: Feature

Slide 12

Slide 12 text

Before Ruby Box: Global Only All classes/modules are shared in the entire Ruby process Ruby Process Application Code App::Func User Library Code DB::Client (v2) Library Code ActiveSupport (v7)

Slide 13

Slide 13 text

Before Ruby Box: Global Only Monkey patches overwrite things globally Ruby Process Application Code App::Func User Library Code DB::Client (v2) Library Code ActiveSupport (v7) class String def +(other) = “self:#{other}” User Library Code

Slide 14

Slide 14 text

Ruby Process Application Code App::Func User Library Code DB::Client (v2) Library Code ActiveSupport (v7) 😵 😵 😵 Before Ruby Box: Global Only Monkey patches overwrite things globally class String def +(other) = “self:#{other}” User Library Code

Slide 15

Slide 15 text

Ruby Process Ruby Box Ruby Box Using Ruby Box Ruby Box provides separation for funky monkey patches! Application Code App::Func User Library Code DB::Client (v2) Library Code ActiveSupport (v7) class String def +(other) = “self:#{other}” User Library Code 😀 😀 😀

Slide 16

Slide 16 text

Real-World Use Cases?

Slide 17

Slide 17 text

Testing in Boxes With world-breaking monkey patches for mocking Ruby Process Application Code Test Case ( _test.rb) Monkey Patches Test Runner Application Code Monkey Patches Application Code Test Case ( _test.rb) Test Case ( _test.rb) Test Case ( _test.b.rb) Test Case ( _test.b.rb) “.b.rb” su ff ix is just my idea - there should be be tt er rules.

Slide 18

Slide 18 text

Ruby Process Ruby Box Running 2 Apps in Boxes With the di ff erent sets of apps/libraries Application Code (v1) App::Func User Library Code DB::Client (v2) Library Code ActiveSupport (v7) Ruby Box Application Code (v2) App::Func User Library Code DB::Client (v3) Library Code ActiveSupport (v8) "QQWXJUI 0MEFSMJCWFSTJPOT "QQWXJUI /FXFSMJCWFSTJPOT For example, LFA is an app server, runs AWS Lambda functions. Application Server supporting Ruby Box

Slide 19

Slide 19 text

˒ Updated “Packaging” Feature Idea from Matz ˒ Loading packages in box, then pulling public APIs from the box ˒ Packages never break other packages or libraries ˒ Many things to be solved to realize this idea ˒ ActiveSupport? Hook points? Memory usage? Packaging w/ Underlying Boxes

Slide 20

Slide 20 text

ˏ੕ཾݢ

Slide 21

Slide 21 text

Tour of Ruby Box

Slide 22

Slide 22 text

˒ Per-box Class/Method De fi nitions ˒ Scripts(.rb) and Extensions(.so) Loading in Boxes ˒ Current Box Management/Detection RUBY BOX INGREDIENTS

Slide 23

Slide 23 text

˒ Per-box Class/Method De fi nitions “Namespace, What and Why” h tt ps://rubykaigi.org/2024/presentations/tagomoris.html ˒ Scripts(.rb) and Extensions(.so) Loading in Boxes “State of Namespace” h tt ps://rubykaigi.org/2025/presentations/tagomoris.html ˒ Current Box Management/Detection This Talk RUBY BOX INGREDIENTS class.c load.c vm.c

Slide 24

Slide 24 text

˒ Box separates class/method de fi nitions ˒ Ruby programs can de fi ne/refer classes/methods anytime ˒ Current box should be determined whenever Ruby runs (and then, classes/methods for the box will be fetched) Current Box Management/Detection

Slide 25

Slide 25 text

# main.rb …… … require_relative(“app”) … p App.foo #=> [“foo”, “bar”] Ruby Code Example # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end p 2 end

Slide 26

Slide 26 text

# main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new p b1 # # … b1.require_relative(“app”) … p b1::App.foo Ruby Code using Ruby Box # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end p 2 end

Slide 27

Slide 27 text

˒ Ruby Box Switching happens only on some Ruby::Box methods ˒ #require, #require_relative, #load (and #eval) ˒ The target code is required/loaded in the receiver box ˒ Box boundary is fi le, but fi le doesn’t determine its box ˒ A fi le can be loaded in 2 boxes Current Box: Dynamic File Scope?

Slide 28

Slide 28 text

# main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo Ruby Code using Ruby Box (revisit) b1 # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end p 2 end

Slide 29

Slide 29 text

In File: Immediately or Later # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo Evaluated immediately De fi nition created De fi nition created Evaluated when called # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end p 2 end

Slide 30

Slide 30 text

app.rb:9:in '': yay (RuntimeError) from app.rb:3:in '' from main.rb:5:in 'Ruby::Box#require_relative' from main.rb:5:in '' Where is it now? (Using Exception) # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end raise “yay” end

Slide 31

Slide 31 text

app.rb:9: [BUG] o.o ruby 4.1.0dev (2026-04-10T21:09:30Z master 044a43f42b) +PRISM [arm64-darwin24] -- Crash Report log information -------------------------------------------- See Crash Report log file in one of the following locations: * ~/Library/Logs/DiagnosticReports * /Library/Logs/DiagnosticReports for more details. Don't forget to include the above Crash Report log file in bug reports. -- Control frame information ----------------------------------------------- c:0006 p:---- s:0022 e:000021 l:y b:---- r:0x0 CFUNC :bug! c:0005 p:0007 s:0018 e:000017 l:y b:0003 r:0x0 CLASS /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:9 c:0004 p:0007 s:0015 e:000014 l:y b:0003 r:0x0 TOP /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:3 [FINISH] c:0003 p:---- s:0012 e:000011 l:y b:---- r:0x0 CFUNC :require_relative c:0002 p:0023 s:0007 E:000de0 l:n b:---- r:0x0 EVAL main.rb:5 [FINISH] c:0001 p:0000 s:0003 E:000888 l:y b:---- r:0x0 DUMMY [FINISH] -- Ruby level backtrace information ---------------------------------------- main.rb:5:in '' main.rb:5:in 'require_relative' /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:3:in '' /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:9:in '' /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:9:in 'bug!' -- Threading information --------------------------------------------------- Total ractor count: 1 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- /Users/s-tagomori/oss/ruby/build/ruby(rb_print_backtrace+0x24) [0x103421e3c] /Users/s-tagomori/oss/ruby/build/../vm_dump.c:1108 /Users/s-tagomori/oss/ruby/build/ruby(rb_print_backtrace) (null):0 /Users/s-tagomori/oss/ruby/build/ruby(rb_vm_bugreport+0x2f8) [0x103422154] /Users/s-tagomori/oss/ruby/build/../vm_dump.c:1456 Where is it now? (Using BUG) # app.rb p 1 module App def self.foo(x=:bar) [:foo, x].map{ it.to_s } end bug! #only on my Ruby end

Slide 32

Slide 32 text

˒ The execution status in Ruby VM ˒ Control Frames are stack Control Frames (rb_control_frame_t) struct rb_control_frame_struct { const VALUE *pc; VALUE *sp; const rb_iseq_t *_iseq; VALUE self; const VALUE *ep; const void *block_code; void *jit_return; }; -- Control frame information ----------------------------------------- c:0006 p:---- s:0022 e:000021 l:y b:---- r:0x0 CFUNC :bug! c:0005 p:0007 s:0018 e:000017 l:y b:0003 r:0x0 CLASS ……/app.rb:9 c:0004 p:0007 s:0015 e:000014 l:y b:0003 r:0x0 TOP ……/app.rb:3 [FINISH] c:0003 p:---- s:0012 e:000011 l:y b:---- r:0x0 CFUNC :require_relative c:0002 p:0023 s:0007 E:000de0 l:n b:---- r:0x0 EVAL main.rb:5 [FINISH] c:0001 p:0000 s:0003 E:000888 l:y b:---- r:0x0 DUMMY [FINISH]

Slide 33

Slide 33 text

˒ Backtrace: “Ruby Level Backtrace” ˒ Translated & fi ltered control frames ˒ Hide C-level informations (show them just like Ruby-level one) ˒ Hide internal frames (DUMMY, IFUNC, etc) Backtrace and Control Frames

Slide 34

Slide 34 text

Finding Current Box # app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo

Slide 35

Slide 35 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo main Finding Current Box

Slide 36

Slide 36 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo main Finding Current Box

Slide 37

Slide 37 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 38

Slide 38 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 39

Slide 39 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 40

Slide 40 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 41

Slide 41 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 42

Slide 42 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 43

Slide 43 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo main Finding Current Box

Slide 44

Slide 44 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 45

Slide 45 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 46

Slide 46 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 47

Slide 47 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo b1 Finding Current Box

Slide 48

Slide 48 text

# app.rb a = 1 module App b = 1 def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } end p b end p a # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new … b1.require_relative(“app”) … p b1::App.foo main Finding Current Box

Slide 49

Slide 49 text

Finding Current Box ˒ Rules to detect current box ˒ Find the closest Ruby frame ˒ If it’s running a C func, trace back to the closest Ruby frame ˒ Find the “LOCAL” variable scope from the Ruby frame ˒ Check the box of the LOCAL env

Slide 50

Slide 50 text

˒ The fl ag about local variable scope ˒ LOCAL: File, Class/Module, Method ˒ Non-LOCAL: Block, Eval, Rescue ˒ “env” fl ag ˒ Control frames and these environments are marked “LOCAL”?

Slide 51

Slide 51 text

˒ “env” is not “ENV”ironment variable ˒ Frame environment ˒ ep: env pointer Control Frame and Environment struct rb_control_frame_struct { const VALUE *pc; VALUE *sp; const rb_iseq_t *_iseq; VALUE self; const VALUE *ep; const void *block_code; void *jit_return; }; typedef struct rb_control_frame_struct rb_control_frame_t; rb_control_frame_t env VALUE LVAR … VALUE LAST_LVAR VALUE ME_CREF // ep[-2] VALUE SPECVAL // ep[-1] VALUE FLAGS // ep[0] VALUE ENV // rb_env_t*

Slide 52

Slide 52 text

˒ Local variables are listed in the tail of env Control Frame and Environment env VALUE d VALUE c VALUE x VALUE ME_CREF // ep[-2] VALUE SPECVAL // ep[-1] VALUE FLAGS // ep[0] VALUE ENV // rb_env_t* def self.foo(x=:bar) c = 1 [:foo, x].map{ it.to_s } d = 2 end

Slide 53

Slide 53 text

ENVs Referenced from Control Frames rb_control_frame_t rb_control_frame_t rb_control_frame_t rb_control_frame_t rb_control_frame_t current cfp ˒ rb_control_frame_t *cfp (control frame pointer) ˒ cfp->ep ˒ ENV size depends on # of local variables ENV ENV ENV ENV ENV ep ep ep ep ep

Slide 54

Slide 54 text

Ruby’s Stack Memory Space ˒ From head: control frames ˒ From tail: ENVs ˒ ENV members are accessed using negative index as ep[-1] Stack Memory Space in CRuby rb_control_frame_t ENV ENV rb_control_frame_t

Slide 55

Slide 55 text

Ruby’s Stack Memory Space Stack in CRuby rb_control_frame_t ENV ENV ENV ENV rb_control_frame_t rb_control_frame_t rb_control_frame_t ˒ From head: control frames ˒ From tail: ENVs

Slide 56

Slide 56 text

Ruby’s Stack Memory Space Stack in CRuby rb_control_frame_t ENV ENV ENV ENV rb_control_frame_t rb_control_frame_t rb_control_frame_t rb_control_frame_t ENV ˒ From head: control frames ˒ From tail: ENVs

Slide 57

Slide 57 text

Ruby’s Stack Memory Space Stack in CRuby rb_control_frame_t ENV ENV ENV ENV rb_control_frame_t rb_control_frame_t rb_control_frame_t rb_control_frame_t rb_control_frame_t ENV ENV Stack Over fl ow!! ˒ From head: control frames ˒ From tail: ENVs

Slide 58

Slide 58 text

˒ M: Frame Magic / Frame Type (15bits + check) METHOD, BLOCK, CLASS, TOP, CFUNC, IFUNC, EVAL, RESCUE, DUMMY ˒ F: Frame Flags (8bits) FINISH, CFRAME, LAMBDA, … ˒ E: Env Flags (4bits) LOCAL, ESCAPED, WB_REQUIRED, ISOLATED ˒ X: Tag for GC marking (to mimic Fixnum) Frame/Env Flags struct rb_control_frame_struct { // …… const VALUE *ep; // …… }; ————————————————————- VALUE ME_CREF // ep[-2] VALUE SPECVAL // ep[-1] VALUE FLAGS // ep[0] M M M M M M M M M M M M M M M M _ _ _ F F F F F F F F E E E E X

Slide 59

Slide 59 text

Frame Types and Env Values (3.4) 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&'

Slide 60

Slide 60 text

˒ ME: Method Entry fl ags, de fi ned_class, method_de fi nition, called_id, owner ˒ Method De fi nition (mdef) (rb_method_definition_struct) can have box (rb_box_t *box) ˒ BH: Block Handler ˒ CREF: Class REFerence fl ags, re fi nements, klass_of_self, next, scope_visibility ˒ Prev EP: Previous Env Pointer ENV Values a = 1 PROC1 = ->(){ a * 2 } module App def self.foo c = 2 [:foo, :bar].map{ s = it.to_s ->(){ s * c } } end end env1 env2 env3 env4 env5 env6

Slide 61

Slide 61 text

˒ ME: Method Entry fl ags, de fi ned_class, method_de fi nition, called_id, owner ˒ Method De fi nition (mdef) (rb_method_definition_struct) can have box (rb_box_t *box) ˒ BH: Block Handler ˒ CREF: Class REFerence fl ags, re fi nements, klass_of_self, next, scope_visibility ˒ Prev EP: Previous Env Pointer ENV Values a = 1 PROC1 = ->(){ a * 2 } module App def self.foo c = 2 [:foo, :bar].map{ s = it.to_s ->(){ s * c } } end end env1 env2 env3 env4 env5 env6

Slide 62

Slide 62 text

˒ ME: Method Entry fl ags, de fi ned_class, method_de fi nition, called_id, owner ˒ Method De fi nition (mdef) (rb_method_definition_struct) can have box (rb_box_t *box) ˒ BH: Block Handler ˒ CREF: Class REFerence fl ags, re fi nements, klass_of_self, next, scope_visibility ˒ Prev EP: Previous Env Pointer ENV Values a = 1 PROC1 = ->(){ a * 2 } module App def self.foo c = 2 [:foo, :bar].map{ s = it.to_s ->(){ s * c } } end end env1 env2 env3 env4 env5 env6

Slide 63

Slide 63 text

˒ ME: Method Entry fl ags, de fi ned_class, method_de fi nition, called_id, owner ˒ Method De fi nition (mdef) (rb_method_definition_struct) can have box (rb_box_t *box) ˒ BH: Block Handler ˒ CREF: Class REFerence fl ags, re fi nements, klass_of_self, next, scope_visibility ˒ Prev EP: Previous Env Pointer ENV Values a = 1 PROC1 = ->(){ a * 2 } module App def self.foo c = 2 [:foo, :bar].map{ s = it.to_s ->(){ s * c } } end end env1 env2 env3 env4 env5 env6

Slide 64

Slide 64 text

Frame Types and Env Values Finding the current box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check MDef Check MDef

Slide 65

Slide 65 text

Frame Types and Env Values Finding the current box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check Prev EP Check Prev EP Check Prev EP Check MDef Check MDef

Slide 66

Slide 66 text

Frame Types and Env Values Finding the current box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check Prev EP Check CFUNC Check Prev EP Check Prev EP Check MDef Check MDef Always main

Slide 67

Slide 67 text

Frame Types and Env Values Finding the current box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check Prev EP Check Prev EP Check Prev EP Check MDef Check MDef 🤔 🤔 Check CFUNC Always main

Slide 68

Slide 68 text

Frame Types and Env Values Finding the current box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #) $3&' 501 0O #) $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check Prev EP Check Prev EP Check Prev EP Check MDef Check MDef 🤔 🤔 😳 😳 CLASS/TOP frames never receive blocks! Check CFUNC Always main

Slide 69

Slide 69 text

Frame Types and Env Values (4.0) Finding the Current Box 'SBNFUZQF 7.@&/7@'-"(@-0$"- 41&$7"- .&@$3&' .&5)0% 0O #) #MPDL)BOEMFS .& .FUIPE&OUSZ #-0$,  1SFW&1 $3&' $-"44 0O #PY SC@CPY@U $3&' 501 0O #PY SC@CPY@U $3&' $'6/$ 0O #) .& *'6/$  1SFW&1 $3&' &7"-  1SFW&1 $3&' 3&4$6&  1SFW&1 $3&' %6..: 0O #) $3&' Check Prev EP Check Prev EP Check Prev EP Check MDef Check MDef Check SPECVAL Check SPECVAL Check CFUNC Always main

Slide 70

Slide 70 text

Finding Current Box: Revisit ˒ Rules to identify current box ˒ Find the closest Ruby frame ˒ If it’s running a C func, trace back to the closest Ruby frame ˒ Find the “LOCAL” variable scope from the Ruby frame ˒ Check the box of the LOCAL env ˒ SPECVAL or ME_CREF->mdef

Slide 71

Slide 71 text

˒ Method de fi nitions can be marked with its box ˒ In Class/Top frames ˒ Class de fi nition frame can be marked with its box ˒ In Top frames ˒ How can we mark the Top frames? Bootstrapping Problem

Slide 72

Slide 72 text

˒ Ruby Box switching happens only on some Ruby::Box methods ˒ #require, #require_relative, #load (and #eval) ˒ The target code is required/loaded in the receiver box ˒ The pushed (TOP) control frame is marked with the loading box Bootstrapping Box: Box#require -- Control frame information ------------------------------------------- c:0005 p:---- s:0019 e:000018 l:y b:---- r:0x0 CFUNC :bug! c:0004 p:0003 s:0015 e:000014 l:y b:0003 r:0x0 TOP ……/app.rb:2 [FINISH] c:0003 p:---- s:0012 e:000011 l:y b:---- r:0x0 CFUNC :require_relative c:0002 p:0023 s:0007 E:000030 l:n b:---- r:0x0 EVAL ./main.rb:5 [FINISH] c:0001 p:0000 s:0003 E:000738 l:y b:---- r:0x0 DUMMY [FINISH]

Slide 73

Slide 73 text

˒ The box to be used on loading fi les, marking TOP frame ˒ $LOAD_PATH is to resolve fi le paths BEFORE loading fi les ˒ Global variables for loading should switch the e ff ective boxes earlier than the current box (after red, before green line frame) The “Loading” Box? -- Control frame information ------------------------------------------- c:0005 p:---- s:0019 e:000018 l:y b:---- r:0x0 CFUNC :bug! c:0004 p:0003 s:0015 e:000014 l:y b:0003 r:0x0 TOP ……/app.rb:2 [FINISH] c:0003 p:---- s:0012 e:000011 l:y b:---- r:0x0 CFUNC :require_relative c:0002 p:0023 s:0007 E:000030 l:n b:---- r:0x0 EVAL ./main.rb:5 [FINISH] c:0001 p:0000 s:0003 E:000738 l:y b:---- r:0x0 DUMMY [FINISH]

Slide 74

Slide 74 text

˒ When calling Box#require (etc) ˒ Marking the current frame with VM_FRAME_FLAG_BOX_REQUIRE ˒ Finding the loading box ˒ Find the VM_FRAME_FLAG_BOX_REQUIRE frame ˒ Fetch cfp->self to get the receiver Ruby::Box instance Or the current box on the cfp (if the self is missing) A New Frame Flag: BOX_REQUIRE

Slide 75

Slide 75 text

-- Control frame information ----------------------------------------------- c:0012 (snip) l:y b:---- r:0x0 CFUNC :bug! c:0011 (snip) l:y b:0003 r:0x0 CLASS …/app2.rb:3 c:0010 (snip) l:y b:0003 r:0x0 CLASS …/app2.rb:2 c:0009 (snip) l:y b:0003 r:0x0 TOP …/app2.rb:1 [FINISH] c:0008 (snip) l:y b:---- r:0x0 CFUNC :require c:0007 (snip) l:y b:0001 r:0x0 METHOD :139 [FINISH] c:0005 (snip) l:y b:0003 r:0x0 CLASS …/app.rb:9 c:0004 (snip) l:y b:0003 r:0x0 TOP …/app.rb:3 [FINISH] c:0003 (snip) l:y b:---- r:0x0 CFUNC :require_relative c:0002 (snip) l:n b:---- r:0x0 EVAL ./main.rb:5 [FINISH] c:0001 (snip) l:y b:---- r:0x0 DUMMY [FINISH] ˒ cfp->self is missing in this case ˒ Kernel#require (etc) is overrided by RubyGems, in the root box ˒ The loading box must be marked near the line calling #require Calling Kernel#require in box

Slide 76

Slide 76 text

˒ In boxes, Object includes Box::Loader having #require (etc) ˒ Box::Loader#require marks its cfp with BOX_REQUIRE ˒ The current box (calling #require on .rb) will be the loading box Inserting Ruby::Box::Loader -- Control frame information ----------------------------------------------- c:0012 (snip) l:y b:---- r:0x0 CFUNC :bug! c:0011 (snip) l:y b:0003 r:0x0 CLASS …/app2.rb:3 c:0010 (snip) l:y b:0003 r:0x0 CLASS …/app2.rb:2 c:0009 (snip) l:y b:0003 r:0x0 TOP …/app2.rb:1 [FINISH] c:0008 (snip) l:y b:---- r:0x0 CFUNC :require c:0007 (snip) l:y b:0001 r:0x0 METHOD :139 [FINIS c:0006 (snip) l:y b:---- r:0x0 CFUNC :require c:0005 (snip) l:y b:0003 r:0x0 CLASS …/app.rb:9 c:0004 (snip) l:y b:0003 r:0x0 TOP …/app.rb:3 [FINISH] c:0003 (snip) l:y b:---- r:0x0 CFUNC :require_relative c:0002 (snip) l:n b:---- r:0x0 EVAL ./main.rb:5 [FINISH]

Slide 77

Slide 77 text

˒ Ruby Box has many details on various spots of Ruby VM ˒ De fi ning things in box: Class/Method/etc de fi nitions (class.c) ˒ Loading things in box: Evaluating scripts / Loading binaries (load.c) ˒ Finding boxes: Executing Ruby programs (vm.c) ˒ Tour must be pleasure, probably……? 🤔 Tour of Ruby Box ≒ Tour of (a part of) Ruby VM

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

Road to Box Building

Slide 80

Slide 80 text

A Personal Story

Slide 81

Slide 81 text

Before RubyKaigi 2023 No future for me to develop Ruby language or runtime… I have nothing to add to Ruby.

Slide 82

Slide 82 text

RubyKaigi 2023 Day 2 2023-05-12 in Matsumoto @shioyama https://rubykaigi.org/2023/presentations/shioyama.html#day2

Slide 83

Slide 83 text

˒ tagomoris/LFA: App server, wri tt en in 2022 Winter ˒ loads multi AWS Lambda functions in a process ˒ separates them incompletely ˒ A blog post about its feature and my motivation ˒ h tt ps://tagomoris.hatenablog.com/entry/2022/12/15/133450 ˒ … then, I forgot the motivation ˒ “Multiverse Ruby” “Yes! I have the motivation on that problem!” “Multiverse Ruby” Shock

Slide 84

Slide 84 text

RubyKaigi 2023 Day 2 Evening 2023-05-12 at a bar “OLD ROCK” in Matsumoto

Slide 85

Slide 85 text

@ ff u_ @tagomoris @kakutani Evening

Slide 86

Slide 86 text

@ ff u_ @tagomoris @kakutani 10PM @shioyama

Slide 87

Slide 87 text

Midnight

Slide 88

Slide 88 text

Ruby Box Day 0

Slide 89

Slide 89 text

˒ Day 11: The 1st commit of Namespace PoC ˒ Day 46: The proposal #19744 “Namespace on read” ˒ Day 78: My 1st talk about this idea at MatueRubyKaigi ˒ Day 166: Ruby Association Grant selected my project ˒ 1Y1D: My talk “Namespace, What and Why” in RubyKaigi 2024 ˒ 1Y3D: Matz “Ruby 4.0 with Packaging based on Namespace” Timeline 1

Slide 90

Slide 90 text

˒ 2Y-26D: My talk “State of Namespace” in RubyKaigi 2025 ˒ 2Y-24D: Matz “Ruby 4.0 with (experimental) Namespace and ZJIT” ˒ 2Y-12D: Pull request submi tt ed ˒ 2Y-1D: Pull request merged (by myself) ˒ 2Y179D: Renamed Namespace to Ruby Box ˒ 2Y227D: Ruby 4.0 Timeline 2

Slide 91

Slide 91 text

˒ 3Y-20D: Opening Keynote in RubyKaigi 2026 Timeline 3

Slide 92

Slide 92 text

˒ 3Y-20D: Opening Keynote in RubyKaigi 2026 ˒ Day 0: Multiverse Ruby Timeline 3

Slide 93

Slide 93 text

˒ 3Y-20D: Opening Keynote in RubyKaigi 2026 ˒ Day 0: Multiverse Ruby ˒ Day -1: “I have nothing to add to Ruby” Timeline 3

Slide 94

Slide 94 text

THINGS HAPPEN SUDDENLY You’ll be motivated, unintentionally

Slide 95

Slide 95 text

No content

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

PARTIES, BARS, EVERYWHERE Thanks to Organizers&Sponsors

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

We’re at the conference! TALK, BE MOTIVATED, ENJOY!

Slide 102

Slide 102 text

A Personal Story (cont.)

Slide 103

Slide 103 text

Road to Box Building

Slide 104

Slide 104 text

Road to Box Building വ ؗ

Slide 105

Slide 105 text

@ ff u_ @tagomoris @kakutani 3 Years Before, Midnight @shioyama

Slide 106

Slide 106 text

@tagomoris @shioyama Let’s name it as “Hako” (meaning “Box”), … and then, sometimes later, Let’s have RubyKaigi at Hakodate. Wow, it’s Hako-Kaigi!

Slide 107

Slide 107 text

Big Thank You @shioyama -san, Ruby Box and This Talk Can’t Be Without You. @shioyama

Slide 108

Slide 108 text

TALK,

Slide 109

Slide 109 text

BE MOTIVATED,

Slide 110

Slide 110 text

ENJOY! Thank you!

Slide 111

Slide 111 text

No content