Techioz Blog

Ruby でクイズ ゲームを作成しています。答えをチェックしてスコアを与えるテスト メソッドがあります。このエラー # が発生します。

概要

このエラー # が発生します。私の知る限り、コードには何も問題はありません。

prompt1 =  "Roses are what, \n a) Blue ,\n b) Red \n c)Orrange"
prompt2 =  "Voilets are what, \n a) Blue ,\n b) Red \n c)Orrange"
prompt3 =  "I love who ?, \n a)Them ,\n b) everyone \n c)You"

ここは質問クラスです

class Question 
  attr_accessor :prompt, :answer
  def initialize(prompt,answer)
    @prompt = prompt
    @answer = answer 
  end
  
end
questions = [
  Question.new(prompt1,"b"),
  Question.new(prompt2, "a"),
  Question.new(prompt3,"c")

]

答えを確認するテスト機能です。 そして結果を表示します。

def testing (questions)
  answer = ""
  score = 0
  for question in questions
    puts question
    answer = gets.chomp()
    if answer == question.answer
      score +=1 
    end
  end
  puts "\n You got #{score} questions right. out of #{questions.length} questions. "
end

testing(questions)

解決策

コードにエラーはありません。表示されているのは、puts 経由でカスタム オブジェクトを印刷するデフォルトの動作です。

その理由は次のとおりです。 put を呼び出すと、IO#puts に従って、次の単純なルールを使用して、指定されたオブジェクトが stdout に出力されます。

オブジェクトは文字列でも配列でもないため、puts はその to_s メソッドを呼び出します。

カスタム クラス (Question クラスなど) には、デフォルトでスーパークラスとして Object があります。これは、次のような Object#to_s を含む、Object からすべてのメソッドを継承することを意味します。

残念ながら、表現は少し誤解を招きます。 to_s は実際には何も出力せず、単に文字列を返すだけです。

ただし、この文字列は # で表示されているものとまったく同じです。 – Question はオブジェクトのクラスで、0x0000022164ee9210 はエンコードされたオブジェクト ID です。

質問に他のもの (プロンプトなど) を出力したい場合は、クラスで to_s をオーバーライドできます。

class Question
  # ...

  def to_s
    prompt
  end
end

上記の結果は次のようになります。

question = Question.new("Roses are ...\n a) Blue\n b) Red\n c) Orange", "b")
puts question

出力:

Roses are ...
 a) Blue
 b) Red
 c) Orange

to_s を実装するときは、文字列を返すだけであることに注意してください。それ自体では何も出力しないでください。つまり、to_s 内で put を呼び出さないでください。