#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».
Я надеюсь, что это даст вам представление о том, что вы могли бы сделать дальше.