2013-03-08 74 views
4
package Bar; 
use Foo; 

sub bar { fooit "hello from bar"; } 

package Foo; 

sub fooit { 
    # Somehow I want this function to know it was called 
    # from the "Bar" module (in this case). 
} 

优选地,这将在不显式传递包含调用模块名称的参数的情况下完成。一个函数可以告诉从哪个模块调用它?

+1

你或许应该解释一下为什么你想知道的,因为这是很难的东西,你可以在所有可能的情况下,依靠对大多数的目的。 – tchrist 2013-03-08 17:54:23

+0

这是为了记录目的,所以我可以说“fooit在00:00:00从酒吧叫来”。你能详细说明这里的陷阱吗? – gcbenison 2013-03-08 17:56:06

+1

我经常编写自己的小调试函数,这样可以工作,所以我可能知道你来自哪里。通常人们不想知道调用框架被编译到哪个包中,而是想知道它的文件名和行号,'warn'和'die'没有给出新行结束符。如果有的话,“陷阱”是任何人都可以写'{package Other; some :: function()}',它不像在'Other.pm'文件或类似的东西。实际上,他们也可以对文件和行进行细化处理,但是我猜如果你不处于某种恶劣的环境中,这并不重要。 – tchrist 2013-03-08 17:59:00

回答

6

内建函数caller可用于获取有关当前调用堆栈的信息。

sub fooit { 
    my ($pkg, $file, $line) = caller; 
    print STDERR "fooit was called from the $pkg package, $file:$line\n"; 
} 
+0

有趣的时间,做一个捆绑'$ CALLER'变量总是包含该信息。 :) – tchrist 2013-03-08 18:01:56

2

caller在标量上下文中没有参数将返回调用者的名称空间。

my $caller = caller(); 

print caller()."\n";  # '.' forces scalar context 

print "".caller(), "\n"; # '.' forces scalar context 

这是非常罕见的,你需要的是,除非你试图复制Carp的潜艇之一的行为。

+0

即使你是,总是有'鲤鱼:: longmess'。 – tchrist 2013-03-08 18:01:10

1

使用内置的caller应该是最简单也是最直接的方法,但Devel::Backtrace也是值得一看的CPAN模块,它可以通过优雅的界面提供更多的细节信息。

package Foo; 
use Devel::Backtrace; 

sub fooit { 
    my $backtrace = Devel::Backtrace->new; 

    print $backtrace->point(1)->package, "\n\n"; 
    print $backtrace; 
} 

package Bar; 

sub bar { 
    Foo::fooit('hello from bar'); 
} 

package main; 

Bar::bar(); 

输出:

Bar 

Devel::Backtrace::new called from Foo (test.pl:5) 
Foo::fooit called from Bar (test.pl:14) 
Bar::bar called from main (test.pl:19) 
相关问题