Возможно ли разместить все переменные и методы внутри класса?

#ruby #class

#ruby #класс

Вопрос:

Извините за вопрос новичка. Я следовал быстрому руководству, чтобы сделать тест Ruby, который я объясню.

Я создал класс, как показано ниже:

 class Question
    attr_accessor :prompt, :answer

    def initialize(prompt, answer)
        @prompt = prompt
        @answer = answer
    end
end
  

Затем я создал переменную в качестве вопроса:

 p1 = "What color is an apple?n(a)redn(b)orangen(c)yellow"
  

Затем массив для хранения вопроса и назначения ответа:

 questions = Question.new(p1, "a")
  

Ниже приведен метод:

 def run_test(questions)
    answer = ""
    score = 0
    for question in questions
        puts question.prompt
        answer = gets.chomp()
        if answer == question.answer
            score  = 1
        end
    end
    puts ("You got "   score.to_s   "/"   questions.length().to_s)
end
  

Теперь я хочу немного модулировать, чтобы класс Question содержал переменную / вопрос, массив / ответ и метод, чтобы я мог ссылаться на него из другого файла (например, основного файла приложения). Возможно ли поместить все эти элементы в класс, чтобы я мог ссылаться на него из другого файла (основного приложения)?

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

Ответ №1:

Добро пожаловать в Stack Overflow и сообщество Ruby!

Есть ли лучший способ сделать это?

Когда дело доходит до программирования, всегда есть другие способы выполнения задач, иногда считающиеся лучшими, иногда хуже, это зависит от конкретного случая. Полезно изучить то, что считается лучшими практиками, и практиковать их, пока это не станет вашим способом кодирования по умолчанию. Поскольку многие вещи в жизни используют лучшие практики в качестве рекомендаций, а не правил.

В вашем случае все было хорошо, пока вы не захотели импортировать код, чтобы повторно использовать его в другом проекте, поэтому выбранная вами абстракция больше не работает, это происходит, и все в порядке, пришло время ее реорганизовать!

Глядя на ваш код в данный момент, класс question — это просто прославленная структура данных, вы могли бы добиться чего-то подобного с помощью хэша { prompt: '', answer: ''} , означающего, что в вашем классе есть часть данных, но нет логической части, мое первое предложение — перенести логику проверки ответов в метод в классе Question .

 class Question
  attr_reader :prompt, :correct_answer

  def initialize(prompt, correct_answer)
    @prompt = prompt
    @correct_answer = correct_answer
  end

  def score(answer)
    return 1 if answer == @correct_answer
    return 0
  end
end
  

Преимущество этого подхода заключается в том, что в конечном итоге вы можете решить сделать что-то вроде «этот вопрос стоит 2 балла», «когда вводимые пользователем данные (several spaces)c(several spaces) я хочу рассматривать как справедливые c «, и это было бы местом для реализации этой логики.

Следующее, что вы можете рассмотреть, это введение нового класса, который представляет собой тест / викторину / экзамен. Этот класс отвечает за выполнение логики, в которой вы реализованы run_test . При этом вы должны иметь возможность импортировать и повторно использовать свой код. При записи этого класса подумайте о возможных вещах, которые вы можете сделать с тестом, можете ли вы «запустить его», «завершить его», «ответить на вопрос», «перейти к следующему вопросу» и так далее.

В программировании очень часто избегают связывания ввода-вывода и вашего кода, IO в данном случае это puts question.prompt и the answer = gets.chomp() .

Можно ожидать, что следующий API будет работать, но это действительно зависит от ваших предпочтений и того, чего вы пытаетесь достичь:

 def run_test(quiz)
  quiz.questions.each do |question|
    puts question.prompt
    answer = gets.chomp()
    quiz.answer(question, answer)
  end
  puts ("You got #{quiz.score} / #{quiz.maximum_score}")
end
  

Вы видите, что при таком подходе основной фокус кода заключается в переборе вопросов и проверке ввода-вывода, если бы вы создавали веб-страницу, вы все равно могли бы использовать класс Quiz и Question , что изменилось бы, так это то, как вы задаете вопрос и как вы получаете ответ. Что вы скрыли от потребителей вашего класса, так это то, как вы оцениваете тест, каков максимальный балл, какой у человека текущий балл?

Другие вещи, которые были у меня в голове, когда я составлял этот код: — должен ли у меня быть start метод, который сбрасывает значение до 0? — должен ли я скрывать вопросы за next_question методом, таким образом, я могу вернуться nil , если больше не осталось вопросов, при текущем подходе можно ответить на тест несколько раз, запустив run_test несколько раз и получив все добавленные баллы «У вас есть 23/10».

Я надеюсь, что это даст вам представление о том, что вы могли бы сделать дальше.