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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
76
Breaking down the Pillars of Observability: From data to outcomes
prathamesh
0
98
Monitoring vs. Debugging
prathamesh
0
170
Handling High Cardinality in Observability
prathamesh
1
110
Setting up Monitoring for Kubernetes
prathamesh
0
300
Monitoring vs. Debugging - SRE BLR Meetup
prathamesh
0
92
Monitoring vs. Debugging - IG Meetup 22nd July
prathamesh
2
120
Pune_User_Group.pdf
prathamesh
0
110
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
290
Game over? The fight for quality and originality in the time of robots
wayneb77
1
160
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
330
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
120
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
From π to Pie charts
rasagy
0
170
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
99
The Spectacular Lies of Maps
axbom
PRO
1
710
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
330
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
160
Code Review Best Practice
trishagee
74
20k
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