Невозможно включить класс в другой класс в Ruby: неинициализированная константа (NameError) - PullRequest
13 голосов
/ 06 февраля 2011

Допустим, у меня есть три класса, каждый из которых определяется в своем собственном файле.например, ClassA в ClassA.rb и т. д. *

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.

Использование Windows7, Ruby 1.9.2, RadRails, все файлы находятся в одном и том же проекте и исходной папке.

Извините, если этот вопрос похож на некоторые другие вопросы здесь, но большинство ответов наразрешение "неинициализированной константы" состоит в том, чтобы "просто потребовать файл".Я пытался, и это не работает.

Ответы [ 2 ]

19 голосов
/ 06 февраля 2011

Я думаю, что ваша проблема в том, что $:, переменная, которая контролирует, где 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
4 голосов
/ 06 февраля 2011

Если я храню все в одном файле и добавляю две строки в ваш код, он отлично работает на 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», потому что он самодокументируется там, где я ищу, но «путь / к / файлу», или, в этом случае, «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, которая позволяет выполнять поиск в текущем каталоге и ниже.

...