为什么Rails / lib模块会阻止加载gem模块?

时间:2013-05-17 16:39:23

标签: ruby-on-rails ruby module

此问题的标题可能需要重命名。有什么建议吗?

在我的Rails应用程序中,/ lib文件夹中有一个名为foo_blaster.rb的旧模块。然后我安装了名为foo_blaster.rb的宝石。在删除原始FooBlaster模块之前,gem中的代码都没有执行。为什么是这样? Ruby不应该结合这两个模块吗?

模块是相同的

# lib/foo_blaster.rb
module FooBlaster
  class Characters
    puts "some characters"
  end
end

# foo_blaster gem files
module FooBlaster
   class Users
   end
end

FooBlaster::Characters #=> some characters
FooBlaster::Users #=> NameError: uninitialized constant FooBlaster::Users

我在这里缺少什么?

Rails 2.3.18, Ruby 1.8.7-p358

2 个答案:

答案 0 :(得分:3)

如果您打开控制台(使用script/console)并检查$LOAD_PATH变量,您应该会看到类似这样的内容:

>> $LOAD_PATH
[
  # some entries...
  [12] "/your/rails/root/app",
  [13] "/your/rails/root/app/controllers",
  [14] "/your/rails/root/app/models",
  [15] "/your/rails/root/app/helpers",
  [16] "/your/rails/root/lib",
  # more entries...
  [27] "/your/ruby/path/lib/ruby/1.8/gems/foo_blaster-0.0.1/lib"
  # rest of entries
]

当您require 'foo_blaster'(可能由Rails,Bundler或其他方法隐式完成)时,Ruby会按顺序搜索$LOAD_PATH中的位置,直到找到文件foo_blaster.rb,加载文件,并停止。在您的情况下,它在应用程序的/ lib目录中找到该文件。永远不会加载gem中的文件。

如果要加载这两个文件,您只需为它们指定不同的名称,并确保require它们都有。例如,您可以将应用程序中的文件重命名为foo_blaster_extensions.rb,然后添加初始化程序以加载它:

# config/initializers/extend_foo_blaster.rb
require 'foo_blaster_extensions'

答案 1 :(得分:0)

如果您的核心应用程序中需要相同的名称文件。你应该在创建gem时遵循最佳实践,即你应该命名你的gem。因此,在这种情况下,核心应用程序不会发生冲突。