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

时间:2011-02-06 01:07:58

标签: ruby include constants require initialization

假设我有三个类,每个类都在自己的文件中定义。例如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,所有文件都在同一个项目和源文件夹中。

如果这个问题类似于此处的其他一些问题,我很抱歉,但解决“未初始化常量”的大部分答案都是“只需要文件”。我试过了,但它没有用。

2 个答案:

答案 0 :(得分:19)

我认为您的问题是$:,即控制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

答案 1 :(得分:4)

如果我将所有内容保存在一个文件中,并在代码中添加两行,则可以在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命令,允许在当前目录及下面搜索。