无法将一个类包含到 Ruby 中的另一个类中:未初始化的常量 (NameError)

Posted

技术标签:

【中文标题】无法将一个类包含到 Ruby 中的另一个类中:未初始化的常量 (NameError)【英文标题】:Unable to include a Class in to another class in Ruby: uninitialized constant (NameError) 【发布时间】:2011-06-22 02:29:08 【问题描述】:

假设我有三个类,每个类都在自己的文件中定义。例如ClassA.rb 中的 ClassA 等...

class ClassA
  def initialize
  end

  def printClassA
    puts "This is class A"
  end
end

class ClassB
  def initialize
  end

  def printClassB
    puts "This is class B"
  end
end

class ClassC

  def initialize
  end

  def bothClasses
    a = ClassA.new
    b = ClassB.new
    a.printClassA
    b.printClassB
  end
end

如您所见,ClassC 需要其他两个类才能正常运行。我认为,需要有一种方法可以在 ClassC 中导入/包含/加载其他两个类。

我是 Ruby 新手,我已经尝试了 load/include/require 的所有排列,但我不知道如何让它运行。

我通常只会得到:

classc.rb:2:in `<class:ClassC>': uninitialized constant ClassC::ClassA (NameError)
    from classc.rb:1:in `<main>'

或者我的 import/include/require 语句出现语法错误。

使用 Windows 7、Ruby 1.9.2、RadRails,所有文件都在同一个项目和源文件夹中。

如果这个问题与此处的其他一些问题相似,我很抱歉,但解决“未初始化常量”的大多数答案是“只需要文件”。我试过了,还是不行。

【问题讨论】:

【参考方案1】:

我认为您的问题是$:,控制require 查找文件的变量,不再包括Ruby 1.9.2 及更高版本中的当前目录(出于安全原因)。要告诉 Ruby 在哪里查找文件,您需要执行以下操作之一:

require_relative 'ClassA' # which looks in the same directory as the file where the method is called

# or #

require './ClassA' # which looks in the current working directory

【讨论】:

【参考方案2】:

如果我将所有内容保存在一个文件中,并在代码中添加两行,它在 1.9.2 上可以正常工作:

class ClassA
  def initialize
  end

  def printClassA
    puts "This is class A"
  end
end

class ClassB
  def initialize
  end

  def printClassB
    puts "This is class B"
  end
end

class ClassC

  def initialize
  end

  def bothClasses
    a = ClassA.new
    b = ClassB.new
    a.printClassA
    b.printClassB
  end
end

c = ClassC.new
c.bothClasses
# >> This is class A
# >> This is class B

这告诉我代码没问题,问题在于您包含文件。

我将前两个类拆分为单独的文件,分别为“classa.rb”和“classb.rb”,然后将文件修改为:

require_relative './classa'
require_relative './classb'

class ClassC

  def initialize
  end

  def bothClasses
    a = ClassA.new
    b = ClassB.new
    a.printClassA
    b.printClassB
  end
end

c = ClassC.new
c.bothClasses

运行它后,我得到了相同的结果,表明它运行正确。

我使用“./path/to/file”,因为它是我正在查找的地方的自我记录,但“path/to/file”,或者在这种情况下,“classa”也可以工作。

然后,我切换到 Ruby 1.8.7,并将 require_relative 行更改为 require,并再次保存文件。从命令行运行它再次正常工作:

require './classa'
require './classb'

class ClassC

  def initialize
  end

  def bothClasses
    a = ClassA.new
    b = ClassB.new
    a.printClassA
    b.printClassB
  end
end

c = ClassC.new
c.bothClasses

出于安全原因,Ruby 1.9+ 删除了当前目录 '.'从require 搜索的目录列表中。因为他们知道我们会用干草叉和火把追捕他们,所以他们添加了require_relative 命令,允许在当前目录及以下目录中进行搜索。

【讨论】:

您是否将它们放入三个单独的文件中?如果它们都在同一个 .rb 文件中,它将正常工作。

以上是关于无法将一个类包含到 Ruby 中的另一个类中:未初始化的常量 (NameError)的主要内容,如果未能解决你的问题,请参考以下文章

将派生类中的对象插入到所述对象的另一个实例中(使用 vector.insert 函数)C++

如何将类名作为变量传递给ruby中的另一个类

为啥将内部类注入同一个外部类中的另一个内部类不起作用?

如何将一个类函数传递给同一个类中的另一个?

无法访问实体类中的字段

如何在Obj C中的另一个类中使用一个类中声明的变量