小编Joe*_*e_P的帖子

为什么 Ruby 在使用双冒号时不将父模块添加到词法范围以进行常量查找?

这个问题的扩展这个问题。答案帮助我了解发生了什么,但我仍在质疑为什么。

在一个模块中定义两个类时,有两种编写方法。

使用模块块:

module Foo
  class FirstClass
    def meth
      puts 'HELLO'
    end
  end

  class SecondClass
    def meth
      FirstClass.new.meth
    end
  end
end

Foo::SecondClass.new.meth
Run Code Online (Sandbox Code Playgroud)

使用双冒号:

module Foo; end

class Foo::FirstClass
  def meth
    puts 'HELLO'
  end
end

class Foo::SecondClass
  def meth
    FirstClass.new.meth
  end
end

Foo::SecondClass.new.meth

Run Code Online (Sandbox Code Playgroud)

两种方式都适用于类定义,但是当使用双冒号时,您不能FirstClassSecondClass不包含FirstClass或写入Foo::FirstClass. 发生这种情况是因为Foo它不是SecondClass用双冒号定义的词法范围的一部分,这可以通过使用Module.nesting.

为什么Foo不用双冒号添加到词法范围?在较低级别的 Ruby源代码的上下文中,为什么ruby_cref只指向Foo::SecondClass而不是ruby_cref指向SecondClassthen 指向Foo

例如:

+---------+       +---------+ …
Run Code Online (Sandbox Code Playgroud)

ruby

6
推荐指数
1
解决办法
124
查看次数

带有模块的 Ruby 类命名空间:为什么我会得到带有双冒号的 NameError 而不是模块块?

我正在处理许多预先存在的文件、类和模块,并试图为框架的不同组件提供更好的命名空间。我一直使用模块作为命名空间的一种方式,主要是因为这似乎是标准约定(并且能够“包含”框架的不同部分可能很有用)。

问题是在全局命名空间下有大量应该存在于模块下的类。例如,假设有一个简单定义为的类:

class FirstClass
  def meth
    puts "HELLO"
  end
end
Run Code Online (Sandbox Code Playgroud)

但现在我想在一个模块中拥有这个类:

使用双冒号:

module Foo; end

class Foo::FirstClass
  def meth
    puts 'HELLO'
  end
end
Run Code Online (Sandbox Code Playgroud)

使用模块块:

module Foo
  class FirstClass
    def meth
      puts 'HELLO'
    end
  end
Run Code Online (Sandbox Code Playgroud)

使用双冒号更简洁,也更容易实现,因为我正在更改许多类定义。这两种方式都有效,我认为它们实际上是一回事,但显然它们不是。与模块块相比,双冒号方法似乎导致每个类中的命名空间不同。例如,在“Foo”下面有两个类:

使用模块块:

module Foo
  class FirstClass
    def meth
      puts 'HELLO'
    end
  end

  class SecondClass
    def meth
      FirstClass.new.meth
    end
  end
end

Foo::SecondClass.new.meth
Run Code Online (Sandbox Code Playgroud)

使用双冒号:

module Foo; end

class Foo::FirstClass
  def meth
    puts 'HELLO'
  end
end

class Foo::SecondClass
  def meth
    FirstClass.new.meth
  end
end

Foo::SecondClass.new.meth

Run Code Online (Sandbox Code Playgroud)

该代码在使用模块块时有效,但不适用于双冒号。使用双冒号,会引发 NameError,因为它解析FirstClass …

ruby

5
推荐指数
1
解决办法
194
查看次数

标签 统计

ruby ×2