Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Journey of Box Building

The Journey of Box Building

RubyKaigi 2026 Opening Keynote, talking about Ruby Box and the story behind it.
https://rubykaigi.org/2026/presentations/tagomoris.html

Avatar for Satoshi Tagomori

Satoshi Tagomori

April 21, 2026

More Decks by Satoshi Tagomori

Other Decks in Technology

Transcript

  1. ా᝷ ૱ (Satoshi Tagomori) @tagomoris SAKURA internet (2024.08ʙ) Cloud Business

    Strategy Division Maintainer/Founder: OSS: Ruby, Fluentd, MessagePack, 
 Norikra, Woothee, …
 Event: ISUCON Service: Pathtraq
  2. ˒ What’s “Ruby Box”? ˒ Tour of Ruby Box ˒

    Road to Box Building The Journey of Box Building
  3. ˒ 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”?
  4. ˒ 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
  5. 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)
  6. 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
  7. 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
  8. 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 😀 😀 😀
  9. 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.
  10. 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
  11. ˒ 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
  12. ˒ Per-box Class/Method De fi nitions ˒ Scripts(.rb) and Extensions(.so)

    Loading in Boxes ˒ Current Box Management/Detection RUBY BOX INGREDIENTS
  13. ˒ 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
  14. ˒ 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
  15. # 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
  16. # main.rb w/ RUBY_BOX=1 …… b1 = Ruby::Box.new p b1

    # #<Ruby::Box:3,user,optional> … 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
  17. ˒ 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?
  18. # 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
  19. 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
  20. app.rb:9:in '<module:App>': yay (RuntimeError) from app.rb:3:in '<top (required)>' from main.rb:5:in

    'Ruby::Box#require_relative' from main.rb:5:in '<main>' 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
  21. 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>' main.rb:5:in 'require_relative' /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:3:in '<top (required)>' /Users/s-tagomori/oss/talk_demo/rubykaigi2026/app.rb:9:in '<module:App>' /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
  22. ˒ 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]
  23. ˒ 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
  24. 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
  25. # 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
  26. # 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
  27. # 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
  28. # 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
  29. # 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
  30. # 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
  31. # 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
  32. # 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
  33. # 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
  34. # 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
  35. # 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
  36. # 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
  37. # 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
  38. # 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
  39. 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
  40. ˒ 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”?
  41. ˒ “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*
  42. ˒ 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. ˒ 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
  49. 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&'
  50. ˒ 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
  51. ˒ 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
  52. ˒ 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
  53. ˒ 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. ˒ 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
  62. ˒ 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]
  63. ˒ 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]
  64. ˒ 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
  65. -- 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 <internal:…/rubygems/core_ext/kernel_require.rb>: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
  66. ˒ 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 <internal:…/rubygems/core_ext/kernel_require.rb>: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]
  67. ˒ 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
  68. Before RubyKaigi 2023 No future for me to develop Ruby

    language or runtime… I have nothing to add to Ruby.
  69. ˒ 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
  70. ˒ 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
  71. ˒ 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
  72. ˒ 3Y-20D: Opening Keynote in RubyKaigi 2026 ˒ Day 0:

    Multiverse Ruby ˒ Day -1: “I have nothing to add to Ruby” Timeline 3
  73. @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!
  74. Big Thank You @shioyama -san, Ruby Box and This Talk

    Can’t Be Without You. @shioyama