Можно ли разместить все переменные и методы внутри класса? - PullRequest
0 голосов
/ 21 апреля 2019

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

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

class Question
    attr_accessor :prompt, :answer

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

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

p1 = "What color is an apple?\n(a)red\n(b)orange\n(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 Ответ

1 голос
/ 21 апреля 2019

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

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

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

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

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

В программировании очень часто избегают соединения ввода-вывода и вашего кода, в данном случае ввода-вывода это puts question.prompt и 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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...