Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Anatomy of constant lookup and autoloading in R...
Search
Prathamesh Sonpatki
March 19, 2016
200
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
120
The Complete Handbook to OpenTelemetry Metrics
prathamesh
1
100
Breaking down the Pillars of Observability: From data to outcomes
prathamesh
0
120
Monitoring vs. Debugging
prathamesh
0
200
Handling High Cardinality in Observability
prathamesh
1
120
Setting up Monitoring for Kubernetes
prathamesh
0
320
Monitoring vs. Debugging - SRE BLR Meetup
prathamesh
0
110
Monitoring vs. Debugging - IG Meetup 22nd July
prathamesh
2
130
Pune_User_Group.pdf
prathamesh
0
130
Featured
See All Featured
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
The Limits of Empathy - UXLibs8
cassininazir
1
680
Exploring anti-patterns in Rails
aemeredith
4
510
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
810
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
830
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
240
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
460
Building AI with AI
inesmontani
PRO
1
1.2k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
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