m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

Perl入学式#5の最終問題1

#6があるようなので一応


Perlの勉強をしているけどなかなか時間が取れない

仕事とかではこっそりネットサーフィンするしかできないので、ちょっと時間を取りにくい。

#5の最終問題1

以下の機能があるYAPCモジュールを実装してください(上級編)
YAPC::is_yet(<日付の文字列>)で, 開催前か開催後かを真か偽で返します(テストをBの人が, コードをAの人が書きましょう)
「8月28日以前」ならば開催前(真), それ以降なら開催後(偽)として扱うことにします
日付のフォーマットは, 「4桁の年/2桁の月/2桁の日」という形にします
例えば, 2014年1月1日は, 「2014/01/01」です.
この上級編はテストもコードも結構難しいです! わからない所があれば, サポーターの人に「どうすればXXXXが出来る?」と聞きいてみましょう

問題の意図を何も理解せずに書いた結果…

環境
[root@localhost last1]# tree
.
+ lib
+ - YAPC.pm
+ test.t

1 directory, 2 files
[root@localhost last1]#
モジュール(YAPC.pm)
package YAPC;

# 年を返す
sub year {
    return 2014;
}

# 月を返す
sub month {
    return 8;
}

# 日付を返す()
sub day {
    return 28;
}

# 開催前か開催後を返すモジュール
# 最終問題の仕様だと日付ではない場合などが記載されていないので
# 日付ではない場合はありえないということを前提にして考える
sub is_yet{
    # 引数を取得
    my $string = shift;
    my $res = 0;

    if($string =~ /^(\d+)\/(\d+)\/(\d+)$/){
        my $date1 = "$1$2$3";
        if("20140828" gt $date1){
            $res = 1;
        }
    }

    return $res;

}

1;
テストコード(test.t)
#!/usr/bin/env perl

use strict;
use warnings;
use lib 'lib';

use Test::More;
use YAPC;

is YAPC::year(), 2014;
is YAPC::month(), 8;
is YAPC::day(), 28;
ok YAPC::is_yet("2014/08/27");
ok !YAPC::is_yet("2014/08/28");
ok !YAPC::is_yet("2014/08/29");

done_testing();
実行結果
[root@localhost last1]# prove test.t  -v
test.t ..
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
1..6
ok
All tests successful.
Files=1, Tests=6,  0 wallclock secs ( 0.04 usr  0.01 sys +  0.04 cusr  0.01 csys =  0.10 CPU)
Result: PASS
[root@localhost last1]#

なんか違う

テストコード上ではエラーにならないけど、なんかコレじゃない感出まくり…
日付ではない場合とか開催中とかそんなものいろいろ必要な感じがする。
今回はここまで…

最後の問題で

ワンランク上の実装へ...
YAPC::is_yetは, 引数として日付の文字列を受け取るのではなく, 「プログラムを実行した, 現在の時間」を利用して実装することもできます
日付をうまく操作するにはTime::Pieceというモジュールを使います
テスト内の時間を操作するにはTest::MockTimeを使ってみてください

とあるので現在時刻を擬似的に制御できるのならそれを考えてみる。