使用Rails自动加载时,名称冲突与顶级常量 [英] Name Clash with Top Level constant when autoloading with Rails

查看:120
本文介绍了使用Rails自动加载时,名称冲突与顶级常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在app/models/dog.rb中有一个类Dog,在app/services/my/deeply/nested/dog.rb中有另一个类Services::My::Deeply::Nested::Dog.

I'm having a class Dog in app/models/dog.rb and another class Services::My::Deeply::Nested::Dog in app/services/my/deeply/nested/dog.rb.

现在在Services :: My(应用程序/服务/my.rb)中,我引用了以下内容之一(无需区分,因为行为在所有情况下都是相同的):

Now in Services::My (app/services/my.rb), I have a reference to one of the following (no need to distinguish, since the behaviour is exaclty the same in all situations):

  • Deeply::Nested::Dog
  • Services::My::Deeply::Nested::Dog
  • ::Services::My::Deeply::Nested::Dog
  • Deeply::Nested::Dog
  • Services::My::Deeply::Nested::Dog
  • ::Services::My::Deeply::Nested::Dog

无论选择哪种选择,我总是会收到以下错误消息:

No matter which of the above I choose, I always get the following error message:

services/my.rb:警告:Services::My::Deeply::Nested::Dog

此外,我的深嵌套的Dog甚至都不会被解释器看到(我是通过使用puts和语法错误发现的,什么也没发生).

Also, my deeply nested Dog never even gets seen by the interpreter (I found out by using puts and syntax errors, nothing happens).

可能的解决方法(我都不喜欢)是:

Possible workarounds (which I all don't like) are:

  • 重命名其中一个Dog类
  • 使用RAILS_ENV = production运行以禁用自动加载并改为使用紧急加载
  • require_dependency指向深度嵌套的狗
  • Rename one of the Dog classes
  • Run with RAILS_ENV=production in order to disable autoloading and use eager loading instead
  • require_dependency that points to the deeply nested dog

作为计算机科学家,我发现上述解决方法都不令人满意.我想了解为什么没有解决方法就找不到我的深层嵌套的Dog,并找出解决该问题的最新Ruby/Rails解决方案.

As a computer scientist, I find none of the above workarounds satisfactory. I would like to understand why my deeply nested Dog is not found without workaround and find out what the state-of-the-art Ruby / Rails solution would be for this problem.

非常感谢.

推荐答案

app/services/my/deeply/nested/dog.rb应该定义My::Deeply::Nested::Dog而不是Services::My::Deeply::Nested::Dog,原因与app/models/dog.rb没有定义Models::Dog而是仅仅.

app/services/my/deeply/nested/dog.rb should define My::Deeply::Nested::Dog and not Services::My::Deeply::Nested::Dog, for the same reason that app/models/dog.rb doesn't define Models::Dog but just Dog.

使用:

#app/services/my/deeply/nested/dog.rb                                                       
module My
  module Deeply
    module Nested
      class Dog
        puts "I'm in %s" % __FILE__
        puts Module.nesting.inspect
      end
    end
  end
end

# app/models/dog.rb
class Dog
  puts "I'm in %s" % __FILE__
  puts Module.nesting.inspect
end

# app/services/my.rb
module My
  puts "I'm in %s" % __FILE__
  puts Module.nesting.inspect
  Dog
  My::Deeply::Nested::Dog
end

您得到了:

Loading development environment (Rails 5.0.0.1)
2.3.1 :001 > My
I'm in /home/ricou/www/new_rails_5_app/app/services/my.rb
[My]
I'm in /home/ricou/www/new_rails_5_app/app/models/dog.rb
[Dog]
I'm in /home/ricou/www/new_rails_5_app/app/services/my/deeply/nested/dog.rb
[My::Deeply::Nested::Dog, My::Deeply::Nested, My::Deeply, My]
 => My 

这篇关于使用Rails自动加载时,名称冲突与顶级常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆