我有一个非常简单的脚本,它使用Test :: MockTime来模拟时间,但time
调用的输出在代码的两个部分中是不同的。
这是脚本:
package mocker;
use strict;
use warnings;
sub abcd {
print "in abcd, time is " . time . "\n";
}
BEGIN {
use Test::MockTime qw(set_absolute_time restore_time);
set_absolute_time(0);
};
sub do_mock {
print "Current epoch in do_mock is: " . time . "\n";
abcd;
restore_time();
}
1;
我在我的脚本中调用mocker::do_mock
:
use strict;
use warnings;
use mocker;
mocker::do_mock;
我希望输出在两个打印语句中都是“0”作为当前时间,但奇怪的是我有这个输出:
Current epoch in do_mock is: 0
in abcd, time is 1450343385
那么,为什么abcd
时间恢复到当前时间?
答案 0 :(得分:2)
Test :: MockTime的documentation解释说“它在编译时覆盖了localtime
,gmtime
和time
。”所以:
print "Before: " . time; # Uses CORE::time()
use Test::MockTime; # Override time()
print "After: " . time; # Uses overridden time()
您可以使用B::Deparse:
查看此内容$ perl -MO=Deparse foo
print 'Before: ' . time;
use Test::MockTime;
print 'After: ' . &CORE::GLOBAL::time();
foo syntax OK
对time()
的第二次调用实际上使用了CORE::GLOBAL::time()
,这是被覆盖的版本。
要修复,请确保在调用time()
之前编译Test :: MockTime:
package mocker;
use strict;
use warnings;
use Test::MockTime qw(set_absolute_time restore_time);
sub abcd {
print "in abcd, time is " . time . "\n";
}
BEGIN {
set_absolute_time(0);
};
sub do_mock {
print "Current epoch in do_mock is: " . time . "\n";
abcd;
restore_time();
}
1;
答案 1 :(得分:1)
您可以看到this answer以更好地了解BEGIN块的工作方式。
这里的要点是它在主体之前执行,但它也必须被编译。这意味着您声明声明和BEGIN块的顺序是相关的。