Ruby:别名子到父命名空间,这样类只能使用父命名空间进行实例化

  • 本文关键字:命名空间 实例化 别名 Ruby ruby
  • 更新时间 :
  • 英文 :


我想只使用父命名空间作为前缀来访问子命名空间类。

我希望我的模型和控制器生活在单独的子文件夹中,并让它们有一个子命名空间,但可以对子命名空间进行别名,以便可以通过根命名空间访问它。

# This is the only class that is in the root namespace
provider = Cool::Provider.new
# Live in models namespace
company = Cool::Company.new
employee = Cool::Employee.new
# Live in controllers namespace
company_controller = Cool::CompanyController.new
employee_controller = Cool::EmployeeController.new

感谢那些回复过一次映射一个类到父命名空间的人,但我在流行的GEM中看到了一种不同的机制,这种机制似乎更自然,我正在努力寻找这种技术。

几个月前,我看到了一个流行的gem(忘记了是哪个gem(,他们在每个子命名空间的底部添加了一些代码,使该类可用,就像它在父命名空间中一样,但我找不到那个gem,也找不到他们是如何做到的。

假设我在这些文件中有一个类的列表

cool/provider.rb
cool/models/company.rb
cool/models/employee.rb
cool/controllers/company_controller.rb
cool/controllers/employee_controller.rb

以下是的分类

module Cool
class Provider
end
end
module Cool
module Model
class Company
end
end
# The GEM I saw, did something here
end
module Cool
module Model
class Employee
end
end 
# The GEM I saw, did something here
end
module Cool
module Controller
class CompanyController
end
end
# The GEM I saw, did something here
end
module Cool
module Controller
class EmployeeController
end
end 
# The GEM I saw, did something here
end
Ruby中实际上并不存在命名空间。Ruby有模块嵌套——每个模块都封装了自己的常量。类也是模块。

当你使用module关键字时,Ruby实际上是这样做的:

ModuleName = Module.new do
# ... 
end

您正在将Module的一个实例链接到一个常量。因此,如果要将Cool::Model::Company"别名"为Company,只需在Company模块中定义一个常量即可。

module Cool
module Model
class Company
end
end
Company = Model::Company
end

但我不明白为什么这很酷,因为它只会对Rails自动加载器造成严重破坏,因为它会查找cool/company.rb的自动加载根,并期望它定义常量。此外,如果你只是想将模块嵌套到外部模块中,并导致潜在的命名冲突,那么模块嵌套的意义何在?

最新更新