Skip to content

Instantly share code, notes, and snippets.

@yucao24hours
Last active December 20, 2015 02:09
Show Gist options
  • Save yucao24hours/6054328 to your computer and use it in GitHub Desktop.
Save yucao24hours/6054328 to your computer and use it in GitHub Desktop.
1. 耳の遠いおばあちゃんのプログラムを書いてみましょう。 おばあちゃんに何を言っても(何をタイプしても)、叫ばない限り (つまり、全部大文字でタイプしない限り)、 は?! もっと大きな声で話しておくれ、坊や! と返事をします。もし叫んだときは、彼女はあなたの言葉を聞いて (少なくとも聞いた気がして)、 いやー、1938年以来ないねー! と大声で返事をします。 プログラムにちょっと真実味 を持たせるため、 1930年から1950年のランダムな数字で毎回違う年を叫ぶようにしましょう。 2. 上で作った、「耳の遠いおばあちゃんのプログラム」を拡張しましょう。 おばあちゃんはあなたに行って欲しくないのです。 あなたがBYEと叫んでもおばあちゃんは聞こえないふりをします。 BYEを3回連続で …
puts 'Hello! May I help you?'
word = gets.chomp
while word != 'BYE'
if word.upcase == word
puts 'Well, it hasn\'t happened since ' + (1930 + rand(21)).to_s + ' !'
else
puts 'Huh? Could you speak up, please??'
end
word = gets.chomp
end
puts 'Thanks. Come back anytime.'
@tkawa
Copy link

tkawa commented Jul 22, 2013

ブログから来ましたー

入力→BYEだったらカウント用変数を++する、そうじゃなかったら0を代入→カウント用変数が3より小さかったらさっきの返答プログラムを実行、これをループ…というふうになるのかな、と思っていたのですけど、

この考え方で全然OKだと思います 👍

「入力→BYEだったら…そうじゃなかったら…」をif ... elseで書こうとしてwhileの位置を見てあれっと思ったのかな、と想像したのですが、
while word != 'BYE'って実は「入力→BYEだったらループを抜ける。そうじゃなかったらループの中身を実行」という意味ともいえるんですよね。だからもうifが入っちゃってる感じ。
実際にループと条件の部分を分離して

while true
  if word != 'BYE'
    ...
  else
    break
  end
end

と書き換えても同じ意味です。
ほら、もう位置が逆にならない気がしませんか?

@willnet
Copy link

willnet commented Jul 22, 2013

細かいですが

puts 'Well, it hasn\'t happened since ' + (1930 + rand(21)).to_s + ' !'

puts "Well, it hasn't happened since #{(1930..1951).to_a.sample} !"

にすると、

  • ダブルクォーテーションでくくると、シングルクォーテーションの前のバックスラッシュがいらなくなる
  • ダブルクォーテーションでくくると、変数展開が使えるので 'hoge' + 'fuga' みたいにしなくてよくなる
  • (1930..1951).to_a.sample は好みかどうか人によりますが、個人的には意図が通じやすいかなと思います

@kwappa
Copy link

kwappa commented Jul 22, 2013

  • ファイル名

rubyでは prettyOldWoman.rb より pretty_old_woman.rb がよいですね。

クラス名は Upper Camel Case、ファイル名は Snake Case とするのが通例です。 autoload がいずれ出てくるので習慣つけましょう。

  • while word != 'BYE'

until word == 'BYE' という書き方もできます。 if value != condition より unless value == condition のほうが意図が伝わりやすい場合もあるので、そのときに適した書き方をしましょう。
この辺はコーディングルールで規定されていることも多そうです。

  • (1930 + rand(21))

Kernel.#rand は range を引数に取るので、rand(1930 .. 1951) とも書けますね。

  • while true

明示的に無限ループを書く場合や脱出条件が複雑だったり複数あったりする場合は Kernel.#loop を使う方がよいかもしれません。

  • word = gets.chomp

2回出てきますが、1回で済ませる方法はないでしょうか?

BYEを3回連続で 叫ばないといけないように変更

続編blog楽しみにしてます! 🌺

@kakutani
Copy link

TRUISH_YEARS = (1930..1950).to_a.freeze
puts 'Hello! May I help you?'
while words = gets.chomp
  case words
  when 'BYE'
    break
  when words.upcase
    puts "Well, it hasn't happened since #{TRUISH_YEARS.sample} !"
  else
    puts 'Huh? Could you speak up, please??'
  end
end
puts 'Thanks. Come back anytime.'
  • 「入力ある限り繰り返す」の意図ならこんかいはwhileで良さそう(条件がややこしいときはloop do...endのが良さそう)
  • 1930から1950っていうのが意図ならそう書きたい(1951とは)。で、その範囲はあらかじめ决まってる。
  • 「入力を受け付ける」と「受け付けた入力に応じて処理をする(何かputsしたり抜けたり)」という境界で分けたほうが扱いやすいとおもう

BYEは3回がんばれ 👵

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment