2013-03-08 73 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) 
相關問題