我正在尝试使用Module#autoload
在我的新项目中为我的课程设置自动加载功能。它几乎正常工作 - 问题在于,首先使用常量进行自动加载,它会出现“未初始化常量”错误,但在第二次使用时,常量会按预期工作。
说明问题的代码:
init.rb:
# Load lib, other directories will be autoloaded
APPLICATION_ROOT=File.expand_path(File.dirname(__FILE__))
$:.unshift(APPLICATION_ROOT)
Dir.glob("#{APPLICATION_ROOT}/patches/*").each {|p| require p}
Dir.glob("#{APPLICATION_ROOT}/lib/*").each {|p| require p}
# Test autoloading
include Autoload
begin
puts Sprite.new.inspect
rescue
puts "Caught an error"
end
puts Sprite.new.inspect # will not error
贴剂/ string.rb:
class String
def camelize
self.split("_").map{|word| word.capitalize}.join
end
end
LIB / autoload.rb:
module Autoload
Dir.glob("#{APPLICATION_ROOT}/app/*/*").each do |path|
classname = File.basename(path).gsub(/.rb$/,'').camelize
autoload classname.to_sym, path
end
end
应用程序/模型/ sprite.rb:
puts "Sprite Required!"
class Sprite
puts "Sprite Defining!"
def initialize
puts "Sprite Initialized!"
end
end
puts "Sprite Defined!"
输出:
Sprite Required!
Sprite Defining!
Sprite Defined!
Caught an error
Sprite Initialized!
#<Sprite:0x000000024ee920>
如何获得我想要的行为(没有初始错误)?
答案 0 :(得分:2)
问题是您在模块autoload
的范围内调用Autoload
。在类似情况下,红宝石期待或创建的是符号Autoload::Sprite
的自动加载,当您想要的只是Sprite
时。
幸运的是,修复很简单:
module Autoload
def self.included(mod)
# ...
# Call autoload on the scope of the includer
mod.autoload ...
end
end
或者您也可以在Object
上明确调用自动加载,因为这是自动加载类的“目标范围”最有可能的地方:
Object.autoload ...