2016-04-08 13 views
1

caseステートメントでループを実行するのがいいかどうかを知りたいと思います。レスポンス(ユーザ入力)が不正な入力であれば、メソッドを呼び出すことはできますか?より良い方法がありますか?ケースステートメントでメソッドを呼び出すことができますruby

def game_type # Selecting humans or computers as players 
    puts "Please select game type by number:" 
    puts "1 - human vs human" 
    puts "2 - computer vs computer" 
    puts "3 - human vs computer" 
    response = gets.chomp.to_i 

    case response 
    when 1 
     puts "human vs human" 
    when 2 
     puts "computer vs computer" 
    when 3 
     puts "human vs computer" 
    else 
     game_type 
    end 
    end 

答えて

3

再帰的に呼び出すメソッドは非常に悪いことです。再帰呼び出しごとに、コールスタックに追加の深さが追加され、深さが予測されず、パフォーマンスが悪いと予測できないためです。可能であれば、再帰は避けるべきです。この場合、再帰呼び出しを必要としないループを使用します。

def game_type 
    loop do 
    puts <<~_ 
     Please select game type by number: 
     1 - human vs human 
     2 - computer vs computer 
     3 - human vs computer 
    _ 
    response = gets.to_i 
    case response 
    when 1 
     puts "human vs human" 
     break 
    when 2 
     puts "computer vs computer" 
     break 
    when 3 
     puts "human vs computer" 
     break 
    end 
    end 
end 
0

この種の相互作用のための標準的なパターンは、文句を言い、別のループのためにあなたを送り返すelse支店を持つことです。

Rubyを実行するときに注意する1つのことは、多くの繰り返しを避けるために、このようなものを通常の構造で定義してください。 「自分を繰り返さない」(DRY)の原則は非常に重要です。それを乾かしてください!この場合はそう

GAME_TYPE_LIST = [ 
    "Human vs. Human", 
    "Computer vs. Computer", 
    "Human vs. Computer" 
] 

# Convert this list to a hash indexed by 1, 2, 3, etc. 
GAME_TYPES = Hash[GAME_TYPE_LIST.each_with_index.map { |type, i| [ i + 1, type ] }] 

将来的にはより多くの種類を追加することがかなり容易になり、加えても、あなたのメニューを提示する超簡単:

同様に
GAME_TYPES.each do |i, type| 
    puts '%d - %s' % [ i, type ] 
end 

、それが来ます選択する時間:

game_type = nil 

begin 
    puts "Enter type:" 

    game_type = gets.chomp.to_i 
end while (!GAME_TYPES[game_type]) 

これは、あなたが正しいことを繰り返してくれるでしょう。

+0

あなたは、そのような 'chomp'を使うよりもよく知っています。 – sawa

+0

@sawa改行を取り除くのは大変なことは何ですか? 'to_i'は気にしないかもしれませんが、私はそれにクリーンなデータを送りたいのです。 – tadman

-1

私は、これはcase文でループを行うには大丈夫な方法であるかどうかを知りたいです。レスポンス(ユーザ入力)が不正な入力であれば、メソッドを呼び出すことはできますか?

ながらでき澤が言ったように、それはパフォーマンス上の理由のために、Rubyで良い習慣ではない、それを行います。

良い方法はありますか?むしろ使用再帰より

loopを使用します。

GAME_TYPES = { 
    1 => "human vs computer", 
    2 => "computer vs computer", 
    3 => "human vs human" 
} 

def game_type 
    loop do  
    puts <<~___ 
     Please select game type by number: 
     1 - human vs human 
     2 - computer vs computer 
     3 - human vs computer 
    ___ 
    selection = gets.to_i 
    if game_type_str = GAME_TYPES[selection] 
     puts game_type_str 
     break 
    end 
    end 
end 

(私も辞書ではなく、コードがはるかに簡潔breakの束を持つよりますcase文を、使用するようにコードを変更ステートメント)。

+0

「私も** **あなたの**コードを辞書を使用するように変更しました」--- **私の**答えからあなたが変更した**ただのものではありませんか?他の回答には寄生しないでください。何か言いたいことがあれば、自分のコードを使ってあなた自身の言葉で書いて、書いたかのようにふりをしないでください。 – sawa

+0

申し訳ありませんが、私はそれをコピーしたと思いますが、本当に 'while 'ブロックを' loop'に変更する百の方法はありません...私は投稿する前に崇高なコードを書いて、私もアップアップしたあなたの答えに言及するために編集)。 –

+1

同一のモード '〜'を持ち、同じ識別子が '_'で、重複した' chomp'を正確に削除したheredocを使って、単一の 'puts'メソッドを使用することはすべて偶然であったとは考えにくいです。 – sawa

関連する問題