Čovječe, gdje mi je konstanta?
Pita se: Nikola Šantić
Developeri vole fileove
require
# a.rb
puts "Hello from A"
# b.rb
require "a.rb"
# => "Hello from A"
Kernel#require
def require(file)
eval File.read(file)
end
$LOAD_PATH = []
def require(file)
full_path = $LOAD_PATH.first do |path|
File.exists?(File.join(path, file))
end
eval File.read(full_path)
end
$LOADED_FEATURES = []
def require(file)
if $LOADED_FEATURES.include?(file)
return true
end
eval File.read(file)
$LOADED_FEATURES << file
end
require
u praksi
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
require 'application_controller'
require 'post'
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
:/
autoloading
+ reloading
Ruby autoload
# lib/special_library.rb
class SpecialLibrary
puts "Hello!"
end
# main.rb
autoload :special_library, "lib/special_library"
#...
SpecialLibrary.new # => Hello!
Constant lookup
module A
module B
class C < D
p WALDO
# 1. Module.nesting => [A::B::C, A::B, A]
# 2. Module.nesting.first.ancestors
# => [A::B::C, D, Object, Kernel, BasicObject]
# 3. A ako ne...
end
end
end
module A
module B
class C < D
p WALDO
# 1. Module.nesting => [A::B::C, A::B, A]
# 2. Module.nesting.first.ancestors
# => [A::B::C, D, Object, Kernel, BasicObject]
end
end
end
module A
module B
class C < D
p WALDO
# 1. Module.nesting => [A::B::C, A::B, A]
end
end
end
module A
module B
class C < D
p WALDO
end
end
end
const_missing
manje poznati rođak method_missinga
module Foo
def self.const_missing(name)
puts "In #{self} looking for #{name}..."
super
end
end
Što sad?
MyModule::SomeClass # => my_module/some_class.rb
config.autoload_paths # =>
# ./apps/*
# ./apps/{controllers,models}/*
config.autoload_paths << Rails.root.join("lib")
Name mapping:
Pretraživanje:
U međuvremenu...
C = "At the top level"
module A
C = "In A"
end
module A
module B
puts Module.nesting # => [A::B, A]
puts C # => "In A"
end
end
module A::B
puts Module.nesting # => [A::B]
puts C # => "At the top level"
end
# /lib/b.rb
module B
end
# /lib/a.rb
module A
B # => B
end
# /lib/b.rb
module B
end
# /lib/a.rb
module A
end
p A::B # => B
# qux.rb
Qux = "I'm at the root!"
# foo.rb
module Foo
end
# foo/qux.rb
module Foo
Qux = "I'm in Foo!"
end
# foo/bar.rb
class Foo::Bar
def self.print_qux
puts Qux
end
end
Foo::Bar.print_qux
# qux.rb
Qux = "I'm at the root!"
# foo.rb
module Foo
end
# foo/qux.rb
module Foo
Qux = "I'm in Foo!"
end
# foo/bar.rb
class Foo::Bar
def self.print_qux
puts Qux
end
end
Foo::Bar.print_qux # => "I'm in Foo!"
# qux.rb
Qux = "I'm at the root!"
# foo.rb
module Foo
end
# foo/qux.rb
module Foo
Qux = "I'm in Foo!"
end
# foo/bar.rb
class Foo::Bar
def self.print_qux
puts Qux
end
end
Foo::Bar.print_qux # => "I'm in Foo!"
Foo::Bar.print_qux
# qux.rb
Qux = "I'm at the root!"
# foo.rb
module Foo
end
# foo/qux.rb
module Foo
Qux = "I'm in Foo!"
end
# foo/bar.rb
class Foo::Bar
def self.print_qux
puts Qux
end
end
Foo::Bar.print_qux # => "I'm in Foo!"
Foo::Bar.print_qux # NameError: uninitialized constant Foo::Bar::Qux
Pouka: koristite ::C
A Gemovi?
# config/application.rb
Bundler.require(*Rails.groups)
Zaključak
rails-autoloading
By Nikola Šantić
rails-autoloading
- 374