如何取消 ruby 常量的命名空间?
How do I un-namespace a ruby constant?
我正在使用不处理命名空间模型的库。我有一个 rails 引擎,其中包含我需要使用的所有 ActiveRecord 模型,因此我使用引擎的名称空间引用它们,例如:TableEngine::Posts.
Ruby 中有没有办法取消帖子 class 的命名空间?
类似于
TableEngine::Posts.demodulize # => Posts
首先你可以添加你需要的常量并将 Class/Module 分配给它(记住两者都只是对象)。您应该复制它以重置名称:
Posts = TableEngine::Posts.dup
之后删除源常量名称:
Object.send :remove_const, :TableEngine
然后:
Posts
# => Posts
TableEngine
# => NameError: uninitialized constant TableEngine
TableEngine::Posts
# => NameError: uninitialized constant TableEngine
更新。为什么需要 dup
:
注意,class SomeClass
是创建类型 Class
对象并将其分配给某个常量的快捷方式:
SomeClass = Class.new
创建 class 时,未设置其名称值:
klass = Class.new
# => #<Class:0x00000001545a28>
klass.name
# => nil
第一次赋值给常量时,名称被赋值并记忆:
Klass = klass
# => Klass
klass.name
# => "Klass"
当您稍后将 Class
类型的对象分配给另一个常量时,它仍然只是同一个对象,由两个常量引用:
NewKlass = Klass
# => Klass
Klass.name
# => "Klass"
NewKlass.name
# => "Klass"
这就是为什么即使删除初始常量,对象仍将保留旧名称的原因。
Object.send :remove_const, :Klass
# => Klass
NewKlass
# => Klass
NewKlass.name
# => "Klass"
Klass
# => NameError: uninitialized constant Klass
对象本身没有改变。改变的是 Object
对象携带的常量列表。
当您复制 Class
类型的对象时,它创建时没有任何名称(它是新对象):
new_klass = NewKlass.dup
# => #<Class:0x000000016ced90>
new_klass.name
# => nil
当你将它分配给新常量时,名称就设置好了。这就是上面第一个例子中它接收新名称的方式:
Posts = TableEngine::Posts.dup
# => Post
我最终使用了@Andrew 建议的解决方案,稍作改动:
::Posts = TableEngine::Posts.dup
添加“::”可防止帖子 class 被创建它的上下文命名空间,例如:
class PostsController < ApplicationController
Posts = TableEngine::Posts.dup # => PostsController::Posts
::Posts = TableEngine::Posts.dup # => Posts
end
我正在使用不处理命名空间模型的库。我有一个 rails 引擎,其中包含我需要使用的所有 ActiveRecord 模型,因此我使用引擎的名称空间引用它们,例如:TableEngine::Posts.
Ruby 中有没有办法取消帖子 class 的命名空间?
类似于
TableEngine::Posts.demodulize # => Posts
首先你可以添加你需要的常量并将 Class/Module 分配给它(记住两者都只是对象)。您应该复制它以重置名称:
Posts = TableEngine::Posts.dup
之后删除源常量名称:
Object.send :remove_const, :TableEngine
然后:
Posts
# => Posts
TableEngine
# => NameError: uninitialized constant TableEngine
TableEngine::Posts
# => NameError: uninitialized constant TableEngine
更新。为什么需要 dup
:
注意,class SomeClass
是创建类型 Class
对象并将其分配给某个常量的快捷方式:
SomeClass = Class.new
创建 class 时,未设置其名称值:
klass = Class.new
# => #<Class:0x00000001545a28>
klass.name
# => nil
第一次赋值给常量时,名称被赋值并记忆:
Klass = klass
# => Klass
klass.name
# => "Klass"
当您稍后将 Class
类型的对象分配给另一个常量时,它仍然只是同一个对象,由两个常量引用:
NewKlass = Klass
# => Klass
Klass.name
# => "Klass"
NewKlass.name
# => "Klass"
这就是为什么即使删除初始常量,对象仍将保留旧名称的原因。
Object.send :remove_const, :Klass
# => Klass
NewKlass
# => Klass
NewKlass.name
# => "Klass"
Klass
# => NameError: uninitialized constant Klass
对象本身没有改变。改变的是 Object
对象携带的常量列表。
当您复制 Class
类型的对象时,它创建时没有任何名称(它是新对象):
new_klass = NewKlass.dup
# => #<Class:0x000000016ced90>
new_klass.name
# => nil
当你将它分配给新常量时,名称就设置好了。这就是上面第一个例子中它接收新名称的方式:
Posts = TableEngine::Posts.dup
# => Post
我最终使用了@Andrew 建议的解决方案,稍作改动:
::Posts = TableEngine::Posts.dup
添加“::”可防止帖子 class 被创建它的上下文命名空间,例如:
class PostsController < ApplicationController
Posts = TableEngine::Posts.dup # => PostsController::Posts
::Posts = TableEngine::Posts.dup # => Posts
end