为什么在特殊情况下Log4perl PatternLayout中的%M和%F不同?

时间:2013-06-28 09:03:18

标签: perl log4perl

原始问题已重新制定,以供日后使用

我发现以下问题很奇怪。在某些情况下,%M和%F指的是不同的文件。例如,以下情况:

Foo.pm 包含

use warnings;
sub x { 2; 1; }
1;

test.pl 包含

#!/usr/bin/perl
use Log::Log4perl qw/:easy/;
Log::Log4perl->easy_init({ file => 'STDOUT', layout => '[%p{1}] %m{chomp} [%l]%n' });
$::log = Log::Log4perl->get_logger;
local $SIG{__WARN__} = sub {
    local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
    $::log->warn(shift);
};
require "Foo.pm";

结果是:

[W] Useless use of a constant in void context at Foo.pm line 2. [main:: Foo.pm (2)]

所以文件是“ Foo.pm ”,但函数是“ main :: ”。

我发现这种奇怪的行为与“require”编译时发生的错误/警告有关。

为什么%M和%F不同?

谢谢,FERcsI

2 个答案:

答案 0 :(得分:0)

    %F File where the logging event occurred
    %M Method or function where the logging request was issued

答案 1 :(得分:0)

最后,我通过一些实验找到了自己问题的答案。

PatternLayout使用“ caller ”条目作为文件名(和行号等)。但是,方法名称有点复杂。在通常情况下,方法名称也可以在下一级“调用者”中使用(同一级别包含 ANON )。但是,在eval(例如请求)的某些特殊情况下,必须在“调用者”中进行多级搜索。

此外,请求在导入的文件中没有“拥有”子程序,因此%M返回包含请求的函数,但文件名和行没有值引用包含的文件。

作为副作用,您无法使用请求的调用者级别:对于任何级别的“caller_depth”(与“调用者”相对),请求的行号无法访问...