2011-12-28 36 views
1

事實證明,我的問題是植根於事實證明我是把一個$的DEBUGVAR前在@EXPORT_OK分配和「使用config_global QW (config DEBUGVAR);「線。既然它沒有提出任何錯誤,我無法知道這是個問題。所以,解決方法是在這些點上將正確的語法放在變量前面。進口perl的變量進口沒有解決價值

所以我試圖得到編寫和導入Perl模塊的掛起。我不知道爲什麼這麼做很困難,但是我在這個看似微不足道的任務中遇到了很多麻煩。這裏是我的模塊的內容:

package global_config; 
use strict; 

require Exporter; 
our @ISA = qw(Exporter); 
our @EXPORT_OK = qw(DEBUGVAR); 

our ($DEBUGVAR); 

our $DEBUGVAR = "Hello, World!"; 

return 1; 

下面是導入模塊我的Perl腳本的內容:

use strict; 

use config_global qw(config, DEBUGVAR); 
our %config; 
our $DEBUGVAR; 


print "variable imported with value: ".$DEBUGVAR; 

輸出爲「變量與值的輸入:」,而不是其他。我的變量似乎失去了它的價值。我究竟做錯了什麼?

編輯:在擺弄了一下,並轉而發出警告之後,我已經將$ DEBUGVAR從未導入過。當我通過$ config_global:DEBUGVAR使用它時,它按預期工作。現在的問題是它沒有被導入到命名空間中。是什麼賦予了?

回答

1

我看到幾個問題:

  • qw()語法,你不應該使用逗號。qw將每個空白分隔的短語放入一個數組元素中。

這兩個是一樣的:

my @bar = qw(foo bar barfu);   #No commas! 
my @bar = ("foo", "bar", "barfu"); #Commas Required 
  • 如果要導出一個變量,你需要把sigil在它的前面。

您有:

our @EXPORT_OK = qw(DEBUGVAR); 

它應該是:

our @EXPORT_OK = qw($DEBUGVAR); 
  • 你應該使用較新的出口商語法:

這裏的新出口商語法:

package global_config; 
use strict; 
use warnings; 

use Exporter 'import'; #Not "require". No need for "@ISA" 

our @EXPORT_OK = qw(DEBUGVAR); 

our $DEBUGVAR = "Hello, World"; 

1; #Makes no real difference, but you shouldn't say "return 1". Just standard. 
  • 最後,你在做什麼輸出變量?這只是一個不好的做法。
    • 出口任何東西現在被質疑 - 甚至功能。它污染用戶的名字空間。 (至少你使用的是@EXPORT_OKAY)。看看File::Spec。默認情況下,它爲其子例程使用完全限定的軟件包名稱。
    • 有問題的變量可通過完整軟件包名稱$global_config::DEBUGVAR訪問,因此不需要導出它。
    • 如果每個人都做到了呢?是的,你上次在幼兒園聽說過這個藉口,但它適用於此。想象一下,如果有幾個模塊出口$DEBUGVAR

周圍有您的窘境幾種方法,但最好是使用面向對象的Perl,幫助建立這個變量,甚至允許用戶去改變它。

package MyPackage; 

use strict; 
use warnings; 
use feature qw(say); 

sub new { 
    my $class = shift; 
    my $debug = shift; #Optional Debug Value 

    my $self = {}; 
    bless $self, $class; 

    if (not defined $debug) { 
     $debug = "Hello, world!"; 

    $self->Debug($debug); 
    return $self; 
} 

sub Debug { 
    my $self = shift; 
    my $debug = shift; 

    if (defined $debug) { 
     $self->{DEBUG} = $debug; 
    } 
    return $debug; 
} 

1; 

要使用這個模塊,我只需創建一個新的對象,和調試會爲我設置:

use strict; 
use warnings; 
use MyPackage    #No exporting needed 

#Create an object w/ Debug value; 
my $obj = MyPackage->new; #Debug is the default. 
say $obj->Debug;   #Prints "Hello, world!" 

# Change the value of Debug 
$obj->Debug("Foo!"); 
say $obj->Debug;   #Now prints "Foo!" 

#Create a new object with a different default debug 
$obj2 = MyPackage->new("Bar!"); 
say $obj2->Debug;   #Print "Bar!"; 

這解決了幾個問題:

  • 它允許多個值因爲每個對象現在都有自己的值
  • 無需擔心名稱空間污染或訪問包變量。同樣,你需要的全部都包含在對象本身中。
  • 由於複雜性隱藏在對象本身內部,因此更容易調試問題。
  • 這是新的首選方法,因此您不妨使用語法並能夠讀取面向對象的Perl代碼。你會越來越多地看到它。
0

你確定你想在這裏逗號:

use config_global qw(config, DEBUGVAR); 

而且,你是不是出口的配置,所以它可能更好地工作爲:

use config_global qw(DEBUGVAR); 

我還刪除最後一個our $DEBUGVAR;,因爲它可能會將其設置爲undef(或至少將它放在「use」行之前) - 但我不確定這一點。

0

你已經得到混淆的名稱,它看起來像:

use config_global ... 

package global_config; 

雖然人們可能會認爲將發出警告。除非你不使用警告...?

ETA:

our @EXPORT_OK = qw($DEBUGVAR); 
        ^ 

此外,你必須在該變量兩個聲明。調試時,您確實需要使用警告,否則,您永遠無法獲得任何地方。

+0

哈哈是的。哇。接得好。我只是修復它,但不幸的是我仍然有同樣的問題。 =/ – dmarra 2011-12-28 16:35:10

+0

@ user984444答案已更新。 – TLP 2011-12-28 16:45:20

1

從包中導出變量不一定是推薦的做法,爲此,您需要使用要導出的變量的實際名稱。在這種情況下,它是$DEBUGVAR而不是DEBUGVAR這將是子例程的名稱。

在使用配置模塊的腳本中,您不需要聲明$DEBUGVAR變量爲our,因爲導入的變量不受嚴格變量的限制。