Подтвердить что ты не робот

Невозможно включить класс в другой класс в Ruby: uninitialized constant (NameError)

Позволяет сказать, что у меня есть три класса, каждый из которых определяет в своем собственном файле. например 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.

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

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

4b9b3361

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