【问题标题】:Ruby, how to reference Root namespace?Ruby,如何引用 Root 命名空间?
【发布时间】:2014-02-11 08:06:23
【问题描述】:

当我有这样的模块时:

module MyModule
  class MyClass
  end
end

我可以访问/修改 MyModule 引用它:

MyModule.const_set("MY_CONSTANT", "value")

但是Root 命名空间,:: 呢?我正在寻找类似的东西:

::.const_set("MY_CONSTANT", "value")

const_set 的事情只是一个例子,请不要试图解决这个具体情况,而是实际引用 Root 命名空间的方式

【问题讨论】:

  • Root 模块是什么意思?需要更清楚一点..
  • 你的意思可能是main 对象,而不是根?或Object 对象?如果Object 执行如下操作:Object.const_set("MY_CONSTANT", "value"),那么您可以在 main 处使用:::MY_CONSTANT

标签: ruby main


【解决方案1】:

什么是根对象?如果您的意思是main 对象,则不能在此级别设置常量:

TOPLEVEL_BINDING.eval('self').const_set("MY_CONSTANT", "value")
# NoMethodError: undefined method `const_set' for main:Object
#   from (irb):71
#   from /home/malo/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'

如果您的意思是Object 对象,请执行以下操作:

Object.const_set("MY_CONSTANT", "value")
# => "value"

那么您可以在main 或任何其他级别使用:

::MY_CONSTANT
# => "value"

添加另一个确认

我们可以使用KernelObject 设置一个常量,并且在这两种情况下都可以从根命名空间访问该常量:

Kernel.const_set("KERNEL_CONSTANT", "value")
Object.const_set("OBJECT_CONSTANT", "value")

puts !!(defined? ::KERNEL_CONSTANT) # => true
puts !!(defined? ::OBJECT_CONSTANT) # => true

但如果我们在 根命名空间 中设置一个常量,这个常量实际上是在Object 中设置的,而不是在Kernel 中:

::ROOT_CONSTANT = "value"

puts !!(defined? Object::ROOT_CONSTANT) # => true
puts !!(defined? Kernel::ROOT_CONSTANT) # => false

【讨论】:

  • 在irb中,Kernel.class#=>Module,表示它是一个特殊的模块,Module.class#=>Object。这就是为什么当你定义 ::ROOT_CONSTANT = "value" 时,在 Kernel 命名空间中你找不到它。
【解决方案2】:

Ruby 中没有根模块之类的东西。

你可以像这样在顶级命名空间中定义一个模块:

::MY_CONSTANT = "value"

如果出于某种原因您不得不使用const_set,您可以这样做:

module Hi
  Kernel.const_set("X", "3")
end

puts X # => 3

Kernel 被混入顶级命名空间,因此您可以通过这种方式有效地在全局命名空间中定义一个常量。

【讨论】:

  • Kernel 不是::,是Object
  • @majioa 你的句子没有意义。 Kernel 是一个模块,Object 是一个包含Kernel 的类,:: 是一个运算符。
  • 我说错了,我的意思是::的正确应用是应用于Object,而不是Kernel
  • @majioa 我不明白你的意思。 :: 是命名空间解析运算符。没有适当的不适当的应用程序吗?
  • 根命名空间是Object,而不是您声称的Kernel::FOO 将在 Object 中查找 FOO,而不是 Kernel
【解决方案3】:

没有像 Root 模块这样的东西,但是你可以在 Object 类上得到一些非常相似的东西:

def bar
  'bar'
end

class A
  def bar
    'not bar'
  end
  def test
    bar
  end
  def test2
    Object.bar
  end
end

A.new.test  #=> 'not bar'
A.new.test2 #=> 'bar'

您可以在此处阅读有关 main 对象的信息:http://banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    相关资源
    最近更新 更多