$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

Test::Time::AtというCPANモジュールをリリースしました

社内でテスト時の時間操作を便利にするTest::Time::At というモジュールがあったので、それをCPAN化してリリースしました。

テスト中の時間を止めて、sleepなどの操作をうまくハンドリングしてくれるモジュールにはTest::Time というモジュールがあります。このモジュールを使っている時に、たまに、ある時間を指定してテストを実行したい時があります。そのような場合は以下のようにすれば実現できます。

use Test::Time;
use DateTime;

my $target_dt = DateTime->new(year => 2015, month => 7, day => 15);
$Test::Time::time = $target_dt->epoch;
my $now = time;


Test::Time::Atを用いると、このような操作を少し便利にする事ができます。do_atという関数を用いると、特定のブロック内だけ時間を指定して実行することが出来ます。

use Test::More;
use Test::Time time => 1;
use Test::Time::At;

is time, 1, 'Test::Timeで指定したので、ここでは1になる';

do_at {
    is time, 1000, 'Test::Time::Atによって、このブロックは1000になる';
    sleep 10;
    is time, 1010, 'ブロック内でsleepすると時間が進む';
} 1000;

is time, 1, 'ブロックを外れると1に戻る';

Time::PieceやDateTimeなど、epochというメソッドを使えるインスタンスも同様に渡すことが出来ます。

use Test::Time;
use Test::Time::At;

use Time::Piece;
use DateTime;

do_at {
    my $now = gmtime;
} Time::Piece->strptime('2015-08-10T06:29:00', '%Y-%m-%dT%H:%M:%S');

do_at {
    my $now = DateTime->now;
} DateTime->new(year => 2015, month => 8, day => 10);

subtest内の時間を指定する場合は、sub_atを利用することでネストを浅くすることも出来ます。

use Test::More;
use Test::Time;
use Test::Time::At;

subtest 'この中の時間を指定したい' => sub_at {
    is time, 1000;
} 1000;


どうぞご利用ください。
https://metacpan.org/pod/Test::Time::At
https://github.com/hatena/Test-Time-At

Emacsで今編集しているPerlコードの無駄なuseを見つける

blog.shibayu36.org

昨日作成したこの機能だが、結局やりたいことは今リファクタリングしたファイルで無駄なuseをしているものを消したいので、サクッと無駄なuseを抽出したいということだった。

ということで現在編集中のファイルに対して、無駄なuseをしているものを探すEmacsの関数を作った。

quickrunを入れておくと使える

(defun git-root-directory ()
  (cond ((git-project-p)
         (chomp
          (shell-command-to-string "git rev-parse --show-toplevel")))
        (t
         "")))

(defun check-perl-used-modules ()
  (interactive)
  (let* ((topdir (git-root-directory)))
    (quickrun :source `((:command . "perl")
                        (:default-directory . ,topdir)
                        (:exec . ("PERL5LIB=lib:local/lib/perl5:$PERL5LIB %c -MTest::UsedModules -MTest::More -e 'used_modules_ok(\"%s\");done_testing()'"))))))

こんな感じで使える。リファクタリングしてすぐに無駄なuse見つけられて便利。


さらにflycheckのようなツールでエラーが出ると便利そうなのでそういう感じにしたい。

Perlで、あるファイルが必要のないモジュールをuseしてないか調べるスクリプト

Test::UsedModulesを使うと使っていないモジュールを検出できる。ユーティリティとしてリファクタリングのあとに、必要なくなったuseをサクッと調べられると、便利なのじゃないかと考えてcheck-perl-used-modulesというコマンドを作ってみた。

check-perl-used-modulesというファイルを適当にPATHが通っているところに用意する。

#!/bin/bash

path=$(git ls-files | peco)
if [ -z "$path" ]; then
    exit
fi
perl -MTest::UsedModules -MTest::More -e "used_modules_ok('$path');done_testing()"

そうするとgitのレポジトリ内からファイルを絞り込んで、チェックしてくれる。こんな感じ。

やってみて思ったけど、やりたいことは今編集しているファイルが不要なuseをしてないかチェックしたいということだった。Emacsでやれという感じなのでまた今度作ろうと思う。