2016-12-12 60 views
5

想象一下,我想在運行時加載模塊。我預計這工作無法在運行時加載`Cwd`(以及其他非核心模塊)

use warnings; 
use strict; 

eval { 
    require Cwd; 
    Cwd->import; 
}; 
if ([email protected]) { die "Can't load Cwd: [email protected]" } 

say "Dir: ", getcwd; 

但它不,根據Bareword "getcwd" not allowed ...

Cwd默認出口getcwd。我嘗試給函數名稱(s)import,我嘗試了其他功能。 它適用於全名say Cwd::getcwd,所以我認爲它不是導入。

這可以作爲嘗試了,我嘗試了一些其他的核心模塊,例如

use warnings; 
use strict; 

eval { 
    require List::Util; 
    List::Util->import('max'); 
}; 
if ([email protected]) { die "Can't load List::Util: [email protected]" } 

my $max = max (1, 14, 3, 26, 2); 
print "Max is $max\n"; 

注意補充  顯然,函數調用括號給出一個線索編譯器。但是,在我看來,問題仍然存在,最後請參閱編輯。另外,上述模塊中的first BLOCK LIST等功能不起作用。


然而,工作數(完善的)非核心,我試圖模塊。更糟和更容易混淆的是,即使使用完全限定名稱,它也不起作用。

如果在運行時使用require,但我們可以想象在編譯時使用的符號(函數)是未知的,但它適用於(其他)核心模塊。我認爲這是在運行時加載的標準方式。

如果我需要動態加載時使用全名然後罰款,但與不一致的是什麼?以及如何我在運行時加載(並使用)非核心模塊?

我也試過Module::Load::Conditional,它沒有工作。

我錯過了什麼,以及如何在運行時加載模塊?  (試圖與5.165.10.1。)


編輯

正如Matt Jacob指出,用括號作品通話,getcwd()。但是,給定perlsub

NAME LIST;#圓括號可選,如果預先聲明/導入。

這意味着導入不起作用,爲什麼仍然存在問題。

此外,必須根據模塊如何加載使用不同的語法並不好。另外,我不能讓非核心模塊以這種方式工作,特別是具有像List::MoreUtils這樣的語法的模塊。

+2

Perl不知道它是一個子例程。你需要:'&getcwd'(不是很好),''使用subs qw(getcwd);'(更好),或者簡單地'getcwd()'(最好)。 –

+0

@MattJacob謝謝,這確實有用。但是,問題仍然存在,正如我在最後添加的說明中所解釋的那樣。 – zdim

+0

當getcwd調用被編譯時,導入還沒有起作用,所以你得到了嚴格的錯誤(或者沒有嚴格的錯誤,把它解釋爲字符串'「getcwd」')。添加圓括號告訴perl它是一個子調用,而不是一個單純的詞。 – ysth

回答

4

首先,這與核心模塊和非核心模塊無關。它發生在解析器必須猜測特定的令牌是否是函數調用時。


eval { 
    require Cwd; 
    Cwd->import; 
}; 
if ([email protected]) { die "Can't load Cwd: [email protected]" } 

say "Dir: ", getcwd; 

在編譯的時候,有在main::符號表中沒有getcwd。沒有任何提示表明它是函數(getcwd()&getcwd),解析器無法知道,並且strict抱怨。


eval { 
    require List::Util; 
    List::Util->import('max'); 
}; 
if ([email protected]) { die "Can't load List::Util: [email protected]" } 

my $max = max (1, 14, 3, 26, 2); 

在編譯的時候,有在main::符號表中沒有max。但是,由於您用圓括號呼叫max,解析器可以猜測它是稍後將定義的函數,因此strict不會發生抱怨。

在這兩種情況下,strict檢查發生在永遠調用import之前。


List :: MoreUtils是特殊的,因爲函數使用原型。如果函數定義在編譯時不可見,原型將被忽略。所以,你不僅需要給解析器提示你正在調用一個函數,你還必須以不同的方式調用它,因爲原型將被忽略:

use strict; 
use warnings 'all'; 
use 5.010; 

eval { 
    require List::MoreUtils; 
    List::MoreUtils->import('any') 
}; 
die "Can't load List::MoreUtils: [email protected]" if [email protected]; 

say 'found' if any(sub { $_ > 5 }, 1..9); 
+0

非常感謝。因此,人們在編譯時需要考慮並在運行時加載時使用不同的語法。很高興知道。 (我已經看到過很多次了,從來沒有見過這種暗示。) – zdim

+0

如問題中所述,我認爲符號不被瞭解,但是我認爲它對其他模塊「起作用」使我相信有些魔術正在完成(對於核心模塊,我認爲)。 – zdim

+0

即使在其他情況下,您也必須考慮解析器,例如'sub foo {...} foo;'沒關係,但是'foo; sub foo {...}不是。所以有些人總是使用括號;它很容易被咬傷。這僅僅是爲什麼你應該避免原型的另一個例子。 – ThisSuitIsBlackNot