a process • Separating apps/libs into isolated spaces • Load apps/libs in a space • Hide changes from apps/libs in the space to others • Run methods de ned in the space with the de nition • Separation for… • Monkey patches fi fi • Different versions of Ruby on Rails
a class Foo in main class Foo def bar = :bar end Main Box Foo.new.bar Foo bar String Array Hash fi fi Root Box Builtin class (unique in the process) User class (de ned per box)
str.upcase De ne a class Foo in main class String def to_s = self.capitalize end Main Box String str.to_s to_s Same object Di erent de nitions per box String Array Hash Builtin class (unique in the process) upcase fi fi fi ff Root Box User class (de ned per box)
self.str(val) myval = “#{val}” puts myval.to_s myval end end class String def to_s = self.capitalize end Making a box Main Box Box b1 # main.rb b1 = Ruby::Box.new String Array Hash fi Root Box Builtin class (unique in the process) User class (de ned per box)
self.str(val) myval = “#{val}” puts myval.to_s myval end end class String def to_s = self.capitalize end Making a box Main Box Box b1 Capitalized str # main.rb b1 = Ruby::Box.new b1.require “capitalized” String to_s String Array Hash fi Root Box Builtin class (unique in the process) User class (de ned per box)
self.str(val) myval = “#{val}” puts myval.to_s myval end end class String def to_s = self.capitalize end Making a box Main Box Box b1 Capitalized str # main.rb b1 = Ruby::Box.new b1.require “capitalized” b1::Capitalized.str(“euruko”) # Euruko String to_s “euruko” String Array Hash Builtin class (unique in the process) capitalize fi Root Box User class (de ned per box)
self.str(val) myval = “#{val}” puts myval.to_s myval end end class String def to_s = self.capitalize end Making a box Main Box Box b1 Capitalized str “euruko” # main.rb b1 = Ruby::Box.new b1.require “capitalized” puts b1::Capitalized.str(“euruko”).to_s # Euruko # euruko String to_s String Array Hash Builtin class (unique in the process) capitalize fi to_s Root Box User class (de ned per box)
:b) module App def self.my_data(a:, b:) MyData.new(a:, b:) end end De ne classes in boxes Main Box Box b1 # main.rb b1 = Ruby::Box.new b1.require “my_data” MyData a b App my_data String Array Hash fi fi Root Box Builtin class (unique in the process) User class (de ned per box)
Main Box Di erent class object Box b1 Box b2 MyData a MyData a b b my_data Array fi fi my_data Hash Root Box ff # main.rb b1 = Ruby::Box.new b1.require “my_data” b2 = Ruby::Box.new b2.require “my_data” App App String # my_data.rb MyData = Data.define(:a, :b) module App def self.my_data(a:, b:) MyData.new(a:, b:) end end Builtin class (unique in the process) User class (de ned per box)
:b) module App def self.my_data(a:, b:) MyData.new(a:, b:) end end De ne classes in boxes Main Box d1 d2 Box b1 Box b2 MyData a MyData a b b App App my_data String Array fi my_data Hash Root Box fi # main.rb b1 = Ruby::Box.new b1.require “my_data” b2 = Ruby::Box.new b2.require “my_data” d1 = b1::App.my_data(a: 1, b: 2) d2 = b2::App.my_data(a: 1, b: 2) Builtin class (unique in the process) User class (de ned per box)
:b) module App def self.my_data(a:, b:) MyData.new(a:, b:) end end De ne classes in boxes Main Box d1 d1 != d2 because d1.class != d2.class d2 String Box b1 Box b1 MyData a MyData a b b App App my_data Array fi my_data Hash Root Box fi # main.rb b1 = Ruby::Box.new b1.require “my_data” b2 = Ruby::Box.new b2.require “my_data” d1 = b1::App.my_data(a: 1, b: 2) d2 = b2::App.my_data(a: 1, b: 2) p(e: d1 == d2) #=> false Builtin class (unique in the process) User class (de ned per box)
Box, Detecting Box • Class de nitions (rb_classext_t) per box • with method tables, super/sub-classes, class/class-instance variables, etc • Library loading in box • like `load(feature, mod)` to de ne loaded classes under mod • using per-box copy of .so/.dll les • Detecting/de ning the current box fi fi fi fi fi • by updating control frame structure / environment
Box, Detecting Box • Class de nitions (rb_classext_t) per box • “Namespace, What and Why” https://rubykaigi.org/2024/presentations/tagomoris.html • Library loading in box • “State of Namespace” https://rubykaigi.org/2025/presentations/tagomoris.html • Detecting/de ning the current box fi fi fi • “The Journey of Box Building” https://rubykaigi.org/2026/presentations/tagomoris.html
in tests? • Applications tests sometimes need monkey patches • to mock library behaviors, IO objects, … • Most of tests can run without box. Ruby Process Application Code Test Case Test Case Just some of them can’t. • How about running tests in boxes? • Running all tests in boxes is too expensive • Run just some of them in boxes! Test Runner Test Case Monkey Patches Test Case Ruby Box
su x test cases in Ruby Box - #382” https://github.com/test-unit/test-unit/pull/382 Loads test code of les like *.box.rb in separated boxes! Merged, and will be released in the next test-unit version (Available with Ruby 4.1 or later) fi ffi • RSpec? Rake::TestTask?
Process • Running 2 sets of RoR applications App/libs ver 1 • For modular-monolith applications • For updating Rails versions • For in-process blue-green deployments • My next goal? or others? Ruby Box Application Server App/libs ver 2 Ruby Box