Namespace
Separating apps/libs into isolated spaces
• Load apps/libs in a space
• Hide changes from apps/libs in a namespace to other spaces
• Run methods de
fi
ned in a space with de
fi
nitions in the space
Slide 5
Slide 5 text
Before Namespace: 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 6
Slide 6 text
Collision: 2 versions of 1 library cause errors
Ruby Process
Library Code
DB::Client (v3)
😵 Application Code
App::Func
User
Library Code
DB::Client (v2)
Library Code
ActiveSupport (v7)
Before Namespace: Global Only
Slide 7
Slide 7 text
Ruby Process
Namespace
Load apps/libs in a space
Namespace
Application Code
App::Func
User
Library Code
DB::Client (v2)
Library Code
ActiveSupport (v7)
Slide 8
Slide 8 text
Ruby Process
Namespace
Hide changes from apps/libs in a namespace to other spaces
Namespace
Application Code
App::Func
User
Library Code
DB::Client (v2)
Library Code
ActiveSupport (v7)
Library Code
DB::Client (v3)
😀
Slide 9
Slide 9 text
Ruby Process
Namespace
Run methods de
fi
ned in a space with de
fi
nitions in the space
Namespace
Application Code
App::Func
User
Library Code
DB::Client (v2)
Library Code
ActiveSupport (v7)
Namespace
Library Code
DB::Client (v3)
Namespace
Application Code
App::Func2
User
Library Code
ActiveSupport (v6)
Application
Code
call call
call
Slide 10
Slide 10 text
at RubyKaigi 2024
Did it work?
• Demo code failed with SEGV (just once! 🤪)
• ‘test-all’ stopped in the middle with SEGV
Slide 11
Slide 11 text
at Jul 1
😵💫
Slide 12
Slide 12 text
at the End of Aug, 2024
Does it work?
• Demo code SHOULD run successfully!
• ‘test-all’ runs to the end!
• 2 failures, 1 error
• 2 failures: new failures after the last rebase
• 1 error: SEGV about (probably) subclasses with GC.compact
Slide 13
Slide 13 text
Namespace design updates
Types of Namespaces
• Before RubyKaigi 2024
• Root namespace
• Main namespace
• (Other) namespaces
• After RubyKaigi 2024
• Root namespace
• Builtin namespace
• (User namespaces)
• Main namespace
• Optional namespaces
Slide 14
Slide 14 text
Types of Namespaces (cont.)
Seeing is Believing
Root
Builtin
(For built-in class/module methods written in Ruby)
Main
Optional
1
Optional
2
……
User
for built-in
classes/modules
for user
scripts
Slide 15
Slide 15 text
Loading .rb into builtin namespace
RubyGems is in the box!
• Classes/Modules available without any #require
SHOULD be in the root (or builtin) namespace
• RubyGems should be in the root/builtin namespace
• RubyGems requires its .rb
fi
les … What happens?
Slide 16
Slide 16 text
User
What Happens with #require
Without RubyGems
Root
Builtin
Main
Optional
1
Optional
2
……
Application
Code
Class/Module
Methods
require ‘foo’
Kernel#require
Call #require
Load .rb in
the caller namespace
(main)
Slide 17
Slide 17 text
User
What Happens with #require
With RubyGems
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
require ‘foo’
Kernel#gem_original_require
Kernel#require
Which one is
the “desired” caller?
Slide 18
Slide 18 text
User
What Happens with #require
With RubyGems, by RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
require ‘bar’
Kernel#gem_original_require
Kernel#require
RubyGems requires
fi
les to be loaded
into the builtin namespace!
Slide 19
Slide 19 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
require ‘foo’
Call #require
(caller is main)
Slide 20
Slide 20 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require require ‘bar’
The .rb code for
Kernel#require
executes any .rb
code
(caller is main)
require ‘foo’
Slide 21
Slide 21 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
require ‘foo’
require ‘bar’
The .rb code
requires any
fi
le
(caller is builtin)
Slide 22
Slide 22 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
require ‘foo’
RubyGems #require
calls the original #require
in the root namespace
(caller is builtin)
require ‘bar’
Slide 23
Slide 23 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
require ‘foo’
The original #require
loads the
fi
le into
the builtin namespace
(caller is builtin)
require ‘bar’
Slide 24
Slide 24 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
RubyGems #require
continues the original
#require call for the main
(caller is main)
require ‘foo’
require ‘bar’
Slide 25
Slide 25 text
User
What Happens with #require
With RubyGems, and RubyGems .rb code
Root
Builtin
Main
Optional
1
Optional
2
……
Ruby Code
Class/Module
Methods
Kernel#gem_original_require
Kernel#require
Finally, the target .rb
fi
le
is loaded into the main
(caller is main)
require ‘foo’
require ‘bar’
Slide 26
Slide 26 text
😳
Slide 27
Slide 27 text
Builtin Namespace
Implicit Refinements
User Namespace
Implicit Mix-ins
Slide 28
Slide 28 text
Namespace is still WIP,
Mostly about just 1 SEGV.
Stay tuned til Ruby 3.4! (or …?)