Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Anatomy of constant lookup and autoloading in R...
Search
Prathamesh Sonpatki
March 19, 2016
200
1
Share
Anatomy of constant lookup and autoloading in Rails
Prathamesh Sonpatki
March 19, 2016
More Decks by Prathamesh Sonpatki
See All by Prathamesh Sonpatki
Secrets to Monitor Kubernetes Workloads
prathamesh
1
110
The Complete Handbook to OpenTelemetry Metrics
prathamesh
1
87
Breaking down the Pillars of Observability: From data to outcomes
prathamesh
0
100
Monitoring vs. Debugging
prathamesh
0
170
Handling High Cardinality in Observability
prathamesh
1
120
Setting up Monitoring for Kubernetes
prathamesh
0
310
Monitoring vs. Debugging - SRE BLR Meetup
prathamesh
0
100
Monitoring vs. Debugging - IG Meetup 22nd July
prathamesh
2
120
Pune_User_Group.pdf
prathamesh
0
110
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.5k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
600
Producing Creativity
orderedlist
PRO
348
40k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
150
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
550
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
300
Marketing to machines
jonoalderson
1
5.3k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
220
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
380
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Technical Leadership for Architectural Decision Making
baasie
3
400
Transcript
Anatomy of constant lookup & autoloading in Rails @_cha1tanya @BigBinary
class PostsController < ApplicationController def index @posts = Post.all end
end
class PostsController < ApplicationController def index @posts = Post.all end
end
It just works! ™
Constants in Ruby
class User < ActiveRecord::Base BASE_URL = “http://example.com” end
class User < ActiveRecord::Base end
User = Class.new(ActiveRecord::Base)
module Admin class Users < ActiveRecord::Base end end
All class & module definitions create constants
class PostsController < ApplicationController def index @posts = Post.all end
end
We refer to constants while using classes or modules
Admin::ApiService::BASE_URL
Constants are stored in modules
API for handling constants
Module.const_set Module.const_get Module.const_missing Module.remove_const
Constant lookup in Ruby
class ApiController BASE_URL = “https://github.com/api/v1” def print_location puts BASE_URL #=>
? end end
Look for the constant inside current scope
class ApiController BASE_URL = “https://github.com/api/v1” def print_location puts BASE_URL” end
end #=> “https://github.com/api/v1
module Admin BASE_URL = “https://github.com/api/v1” class ApiController def print_location puts
BASE_URL #=> ? end end end
Look for the constant in the parent namespace
module Admin BASE_URL = “https://github.com/api/v1” class ApiController def print_location puts
BASE_URL end end end #=> “https://github.com/api/v1”
module SuperAdmin BASE_URL = “https://github.com/api/v1” module Admin class ApiController <
BaseController def print_location puts BASE_URL #=> ? end end end end
Keep looking in the parent namespaces
module SuperAdmin BASE_URL = “https://github.com/api/v1” module Admin class ApiController <
BaseController def print_location puts BASE_URL end end end end #=> “https://github.com/api/v1”
class BaseController BASE_URL = “https://github.com/api/v1” end class ApiController < BaseController
def print_location puts BASE_URL #=> ? end end
class BaseController BASE_URL = “https://github.com/api/v1” end class ApiController < BaseController
def print_location puts BASE_URL end end #=> “https://github.com/api/v1”
Look for the constant in the ancestors chain
class BaseController BASE_URL = “https://github.com/api/v2” end module Admin BASE_URL =
“https://github.com/api/v1” class ApiController < BaseController def print_location puts BASE_URL #=> ? end end end
module Admin BASE_URL = “https://github.com/api/v1” class ApiController < BaseController def
print_location puts BASE_URL end end end #=> “https://github.com/api/v1”
class BaseController BASE_URL = “https://github.com/api/v2” end module Admin class ApiController
< BaseController def print_location puts BASE_URL end end end #=> “https://github.com/api/v2”
Search in namespaces
Search in namespaces Search in ancestors tree
module SuperAdmin BASE_URL = “https://github.com/api/v1” module Admin BASE_URL = “https://github.com/api/v2”
end end
module SuperAdmin class Admin::ApiController def print_location puts BASE_URL #=> ?
end end end
module SuperAdmin class Admin::ApiController def print_location puts BASE_URL #=> ?
end end end
module SuperAdmin class Admin::ApiController def print_location puts BASE_URL end end
end #=> “https://github.com/api/v1”
module SuperAdmin BASE_URL = “https://github.com/api/v1” module Admin BASE_URL = “https://github.com/api/v2”
end end
Module.nesting
module SuperAdmin class Admin::ApiController puts Module.nesting end end
[SuperAdmin::Admin::ApiController, SuperAdmin]
[SuperAdmin::Admin::ApiController, SuperAdmin]
SuperAdmin::Admin::ApiController Not Found
[SuperAdmin::Admin::ApiController, SuperAdmin]
module SuperAdmin BASE_URL = “https://github.com/api/v1” module Admin BASE_URL = “https://github.com/api/v2”
end end
SuperAdmin::Admin
SuperAdmin::Admin Not Checked!
Ruby’s constant lookup algorithm**
Search in current namespace
Continue searching up in parent namespaces**
All namespaces are exhausted
Search in ancestors chain of the innermost class/module
Ancestors chain is exhausted
Module.const_missing(const_name)
Entry point for Rails!
# activesupport/lib/../dependencies.rb def const_missing(const_name) …… end
Autoloading in Rails
Loading mechanism
require v/s load
require require’s only once!
load will load and execute every time!
require in production
require in production load in development
config.cache_classes
Autoload Paths
config.autoload_paths
app/assets app/channels app/controllers app/controllers/concerns app/helpers app/jobs app/mailers app/models app/models/concerns test/mailers/previews
Similar to $LOAD_PATH in Ruby
Constant lookup by Rails
class PostsController < ApplicationController def index @posts = Post.all end
end
PostsController ApplicationController Post
PostsController
class PostsController < ApplicationController def index @posts = Post.all end
end
Constants after class or module
No autoloading by Rails
ApplicationController
class PostsController < ApplicationController def index @posts = Post.all end
end
Top level constant
app/assets/application_controller.rb
app/assets/application_controller.rb app/channels/application_controller.rb
app/assets/application_controller.rb app/channels/application_controller.rb app/controllers/application_controller.rb # FOUND!
Post
class PostsController < ApplicationController def index @posts = Post.all end
end
PostsController::Post
Namespaced constants
app/assets/posts_controller/post.rb app/channels/posts_controller/post.rb app/controllers/posts_controller/post.rb …
app/assets/posts_controller/post app/channels/posts_controller/post app/controllers/posts_controller/post …
Automatic modules
module Admin end module Admin class User < ActiveRecord::Base end
Admin::User
Module acting as namespace
app/models/admin
app/models/admin app/models/admin/user.rb
Admin = Module.new
Coming back to Post
app/assets/posts_controller/post app/channels/posts_controller/post app/controllers/posts_controller/post …
PostsController::Post # Not Found
Search for Post constant
app/assets/post.rb app/channels/post.rb app/controllers/post.rb … app/models/post.rb # FOUND!
Qualified constants
module Admin class User < ActiveRecord::Base end end Admin::User #
Qualified constant
class User < ActiveRecord::Base end User # Top level constant
Admin::User
admin/user.rb
admin/user.rb
user.rb
user.rb
Admin::User
Name error when not found
Constant lookup by Rails
Look for regular .rb file
Look for automatic module
Repeat search in parent namespace**
The file is found, the constant is found
File found, constant not defined
LoadError
Constant not found, File not found
NameError
Constant Reloading
config.cache_classes = false
List of monitored files
config/routes.rb Locales Ruby files under autoload paths db/schema.rb & db/structure.sql
Module.remove_const
Wipe out all autoloader constants at the start of request
@posts = Post.all
Module.const_missing again!
Reloading != Reloading
Reloading == Wiping
Convenient to wipe out & wait for autoload to kick!
What happens with Gems?
# config/application.rb Bundler.require(*Rails.groups)
Gems are already require’d
Unless require: false
Gotchas
Side effects of assumptions by Rails
Nesting information is not passed
module Admin class User < ActiveRecord::Base end end
class User < ActiveRecord::Base end
class Admin::UsersController def index @users = User.all end end
Admin::User or User?
class Admin::UsersController def index @users = User.all end end #
app/models/user.rb # In Ruby
class Admin::UsersController Module.nesting #=> [Admin::UsersController] end # app/models/user.rb # In
Ruby
class Admin::UsersController def index @users = User.all end end #
app/models/admin/user.rb # In Rails
module Admin class UsersController def index @users = User.all end
end
Prefer relative constants
class Admin::UsersController def index @users = Admin::User.all end end #
app/models/admin/user.rb
Don’t mix require and autoloading
require ‘user’ class Admin::UsersController def index @users = User.all end
end
Convention over configuration
Follow the contract and you will be happy!
Thanks! @_cha1tanya @BigBinary