Как организовать каталоги и файлы для вложенного класса

У меня есть такие классы:

require 'active_support/core_ext'

class Shelf
  def initialize
    @books = {}
  end
  def book(code: code)
    @books[code] if @books.has_key?(code)
    @books = Book.new(code: code)
  end
end

class Shelf::Book
  def initialize(code: code)
    @code = code
  end
end

Работает нормально, если я напишу это в файле.

Я хочу разделить классы на два файла shelf.rb а также shelf/book.rb, но когда я пишу require_relative 'shelf/book' в shelf.rb то не получается, потому что class Shelf еще не определено.

Как мне организовать файлы и каталоги? Или я использую вложенный класс совершенно неправильно?

2 ответа

Решение

Вы можете написать другой файл, который не содержит определения классов, но который будет использоваться для запуска вашей программы / скрипта.

В верхней части этого файла

require_relative 'shelf'
require_relative 'shelf/book'

#more code instructions

Вам не нужно require 'shelf/book' в полке.рб

Прочитайте это для именования *.rb файл. Согласно этому, если у вас есть класс Shelf:

class Shelf
end

тогда ваше имя файла должно быть shelf.rbи если у вас есть класс с именем: Shelf::Bookтогда имя файла book.rb должен находиться в каталоге полки (конечно, это не является обязательным или обязательным, чтобы иметь его в каталоге полки, но это хорошее соглашение, которому нужно следовать, так как любой другой разработчик сможет легко найти ваш файл book.rb):

class Shelf::Book
end

Но ваша проблема в том, как вы требуете Shelf::Book, в Shelf, для этого вам нужно позвонить require_relative 'shelf/book' внутри Shelf определение класса, так как Ruby не будет знать о Shelf быть классом до этого. Как это:

class Shelf
  require_relative 'shelf/book'
end

Однако, если вы не хотите Shelf Определение класса для выдачи ошибки независимо от того, где вы используете строку: require_relative 'shelf/book' тогда поменяю тебя shelf/book.rb что-то вроде этого:

class Shelf
  class Book
    def initialize(code: code)
      @code = code
    end
  end
end

Потому что здесь Ruby открывает / создает класс Shelf и не выдаст эту ошибку:

`': неинициализированная константа Shelf (NameError)

Другие вопросы по тегам