Re: 【だいたいあってる時計】乱数の代わりに配列をつかってみたよ
kondoyuko さんのRuby修行のフォローです
id:kondoyuko:20110111:1294754578 で書かれているプログラムへのコメントです。
(はてなDiary のコメント内にはてな記法を使う方法がようわからんかった orz
作ろうとされている辻褄時計の目指しているものがいまいちつかめていない(というか経緯を知らない)ので、プログラムのお作法的なところでいくつかアドバイスを。
オブジェクト名と collect メソッド
ary = [] for i in 0..20 ary << 0.1 * i end
まず、ary っていうオブジェクト名(変数名)は、"配列"ということを意味しているんだろうけど、この場合は、"時計がどれだけ狂う(drift)するかの秒数のテーブル"ということのようだから、clock_drifts とでもしてみましょうか。
プログラムでは、オブジェクト名、メソッド名にわかりやすいものをつけて行く習慣がとてもだいじです。ima の方はとてもわかりやすいw
次に 0..20 という範囲オブジェクト(Rangeクラスのオブジェクト)は、Enumerableモジュールをインクルードしているので、配列オブジェクトと同じように collect という便利なイテレータメソッドが使えます。
以下、irb で示します。
irb(main):021:0> (0..5) => 0..5 irb(main):022:0> (0..5).class => Range irb(main):023:0> (0..5).to_a => [0, 1, 2, 3, 4, 5] irb(main):024:0> (0..5).collect{|i| i* 0.1 } => [0.0, 0.1, 0.2, 0.3, 0.4, 0.5] irb(main):025:0> a = (0..5).collect{|i| i* 0.1 } => [0.0, 0.1, 0.2, 0.3, 0.4, 0.5] irb(main):026:0> a => [0.0, 0.1, 0.2, 0.3, 0.4, 0.5] irb(main):027:0> a.class => Array
つまり、clock_drifts は、以下のように一行で定義できます。
clock_drifts = (0..20).collect{|i| i* 0.1 }
ちょっとクラスプログラミング風に
わたしが同じものを書くとたぶんこうなるだろうというものを。
loop 周りはちょっと動作を変えました start_ticking すると、
すぐに現在時刻を表示して無限ループに入ります。
class TsujitsumaClock CLOCK_DRIFTS = (0..20).collect{|i| i* 0.1 } def self.sleep_random sleep(CLOCK_DRIFTS.choice) end def self.start_ticking ima = Time.now loop do puts ima ima += 1 self.sleep_random end end end TsujitsumaClock.start_ticking
ちょっとしたロジックでも名前をつけてメソッドにする習慣をつけておくと、見通しがよくなり、テストや評価も楽です。
> 結果、よく解らん!!!あんまり変わんないような気がする。
と言うてはった、点も sleep_random というクラスメソッドの中だけを書き換えて、いろいろ統計を取ってみる・テストしてみればいいわけで。
で、統計を取って評価するプログラムも書いてみようかと思ったけど、もう、夜も遅いので今日はここまで。