gpt4 book ai didi

ruby-on-rails-3 - 与 "LoadError"命名空间/自动加载不一致的 'lib' 行为

转载 作者:行者123 更新时间:2023-12-03 10:56:50 24 4
gpt4 key购买 nike

我们刚刚在“lib”中创建了一个新文件,它引发了一系列涉及加载错误的问题。

/lib/response_set.rb:

module MyCompany
class ResponseSet < Array
...
end
end

/spec/lib/response_set_spec.rb
require 'spec_helper'

describe MyCompany::ResponseSet do
describe "..." do
...
end
end

在 Rspec 中运行此规范在到达第一个“描述”时会给我们以下错误:
/Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:492:in `load_missing_constant': Expected /Users/my_stuff/projects/my_project/lib/response_set.rb to define ResponseSet (LoadError)
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/backward_compatibility.rb:20:in `const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-expectations-2.5.0/lib/rspec/expectations/backward_compatibility.rb:6:in `const_missing'
from /Users/my_stuff/projects/my_project/spec/lib/response_set_spec.rb:4:in `<top (required)>'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `load'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `block in load_spec_files'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `map'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `load_spec_files'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/command_line.rb:18:in `run'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:55:in `run_in_process'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:46:in `run'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:10:in `block in autorun'

然而!很长一段时间以来,我们一直在使用许多其他具有相同结构的文件。例如,这是另一个自创建以来一直运行良好的产品:

/lib/smart_set.rb
module MyCompany
class SmartSet < Array
...
end
end

和/spec/lib/smart_set_spec.rb
require 'spec_helper'

describe MyCompany::SmartSet do
describe "..." do
...
end
end

该文件具有相同的结构,但完全没有问题。

ResponseSet(问题类)显然没有明显的原因存在加载问题。在 rails 控制台中,我第一次尝试创建一个时出现错误,但之后我可以创建一个:
Loading development environment (Rails 3.0.4)
ruby-1.9.2-p136 :001 > rs = MyCompany::ResponseSet.new
LoadError: Expected /Users/my_stuff/projects/my_project/lib/response_set.rb to define ResponseSet
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:492:in `load_missing_constant'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:503:in `load_missing_constant'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
from (irb):1
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands/console.rb:44:in `start'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands/console.rb:8:in `start'
from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
ruby-1.9.2-p136 :002 > rs = MyCompany::ResponseSet.new
=> []

此外,添加
require 'response_set'

response_set_spec.rb 顶部的允许这些测试运行。但是 smart_set_spec.rb 不需要这样的东西。

application.rb 中有以下内容:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/**/"]

现在,我知道 Rails 对文件结构应该如何匹配这些类型的命名空间结构有某种看法,为此我们已经重组了我们的模块和文件。似乎已经解决了这个问题(尽管我们在运行完整的测试套件时看到了一些其他奇怪的加载错误 - 这些已经神秘地消失了)。尽管如此,这里的每个人都对 Rails 如此不一致感到困惑和不快,我们想知道为什么。如您所见,就命名空间和文件结构而言,有两个相同的文件,它们的处理方式完全不同。事实上,我们在“lib”的顶层还有十几个其他文件,它们具有类似的命名空间,从未引起任何问题。谁能解释这里到底发生了什么?

最佳答案

我们有一个类似的问题,经过挖掘,原来是由 Rails 3.x 和 autoload_paths 中的更改引起的。 .

我们的案例只出现在测试中(RAILS_ENV=test)。当 Rails 加载 Controller 时,它争先恐后地寻找每个控制​​器的匹配模型(由于在初始化程序中设置了 ActionController::Base.wrap_parameters)。最终它归结为上述方法(load_missing_constant)。由于我们的 autoload_paths 包含 lib 和 lib/**,Rails 从 lib 下的所有子目录中提取了所有文件。不幸的是,从子目录加载时,它似乎忽略了隐含的命名空间。它期望 foo/base.rb 定义 BaseFoo::Base .这似乎是核心缺陷:load_missing_constant调用 search_for_file它返回任何名称匹配的文件(例如,在我的示例中,返回 foo/base.rb 因为它与 base.rb 匹配)。

很难说这是否是 Rails 中的错误——它违反了 Ruby 假设的命名空间到目录的映射——或者是对 autoload_paths 的误用。

我们现在已经通过删除 lib/** 来解决这个问题。来自我们的autoload_paths并将必要的 require 语句添加到 application.rb。

关于ruby-on-rails-3 - 与 "LoadError"命名空间/自动加载不一致的 'lib' 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7081782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com