我正在创建一个gem,这是我的结构:
lib/
| myapp.rb
| myapp/
| version.rb
| configuration.rb
| use_cases/
| base_use_case.rb
| entity1/
| show_entity.rb
spec/
myapp.gemspec
我想让我的类ShowEntity继承自BaseUseCase。
module MyApp::UseCases::Entity1
class ShowEntity < BaseUseCase
end
end
但是我收到以下错误
in `<module:Entity1>': uninitialized constant MyApp::UseCases::Entity1::BaseUseCase (NameError)
在myapp.rb中我需要每个课程,但我仍然会收到错误。
这是我第一次真正理解模块和类如何协同工作并在gem项目中需要它们,因此任何帮助或解释我为什么会遇到错误都会很棒。
答案 0 :(得分:1)
在您的代码中:
module MyApp::UseCases::Entity1
class ShowEntity < BaseUseCase
end
end
Ruby将首先在当前模块BaseUseCase
中查找MyApp::UseCases::Entity1
。假设此类在MyApp::UseCases
下定义以匹配您的文件结构,则不会在那里找到它。 Ruby然后查看封闭范围以尝试查找该类。但是,由于您使用了双冒号语法,因此封闭范围是顶级的, not MyApp::UseCases
正如您所期望的那样。 Ruby“跳过”语句module MyApp::UseCases::Entity1
中的所有名称空间。
如果您定义了这样的类,它应该可以工作:
module MyApp::UseCases
module Entity1
class ShowEntity < BaseUseCase
end
end
end
此处,当在当前范围内找不到BaseUseCase
时,搜索的封闭范围为MyApp::UseCases
。 Ruby一次退回一个module
语句,因为现在有Entity1
的单独声明,下一个范围是MyApp::UseCases
而不是顶级。如果直接在BaseUseCase
下定义了MyApp
,那么此代码也无效,因为在MyApp::UseCases::Entity1
和MyApp::UseCases
下找不到它之后,搜索的下一个范围将是顶级。
要解决此问题,您应该根据需要细分module
声明,或者明确定义BaseUseCase
的完全命名空间名称:
class ShowEntity < ::MyApp::UseCases::BaseUseCase