2013-05-20 138 views
2

我已經離開了Perl世界太久了。我想創建一個子模塊並訪問它的功能。我基本上只是錯過了如何連接這些和訪問方法。如何創建子模塊?

家長例如:WWW ::富

package WWW::Foo 
use strict; 
use warnings; 
require Exporter; 
our @ISA = qw(Exporter); 
our %EXPORT_TAGS = ('all' => [ qw(new) ]); 
our @EXPORT_OK = (@{ $EXPORT_TAGS{'all'} }); 
our @EXPORT = qw(); 
our $VERSION = '0.01'; 

sub new { 
    my ($package) = @_; 

    $package::account_name = "Paul"; 
    return bless({}, $package); 
} 

兒童例如:WWW ::富::酒吧

package WWW::Foo::Bar 
use strict; 
use warnings; 
require Exporter; 
our @ISA = qw(Exporter); 
our %EXPORT_TAGS = ('all' => [ qw(new) ]); 
our @EXPORT_OK = (@{ $EXPORT_TAGS{'all'} }); 
our @EXPORT = qw(); 
our $VERSION = '0.01'; 

sub print_name { 
    my ($package) = @_; 
    # Access parent's package and do basic print. 
    return; 
} 

腳本示例

#!/usr/bin/perl -w 
use strict; 
use WWW::Foo; 
use WWW::Foo::Bar; 

my $foo = new WWW::Foo(); 
# Access WWW::Foo::Bar's print_name function 
+2

出口'new'是沒有任何意義 – ikegami

+0

正如我說我還沒有在perl的世界很長一段時間,您的評論是關於作爲出口新的一樣有價值。 – paulj

回答

5

這是一個簡短的工作示例。

use strict; 
package WWW::Foo; 

sub new { 
    my ($package) = @_; 
    my $self = bless {}, $package; 
    $self->{account_name} = "Paul"; 
    return $self; 
} 


package WWW::Foo::Bar; 
use base "WWW::Foo"; 

sub print_name { 
    my ($self) = @_; 
    my $name = $self->{account_name}; 
    print "Hello $name\n"; 
} 


package main; 
my $foo = WWW::Foo::Bar->new(); 
$foo->print_name(); 

這裏是發生了什麼變化:

  1. 我已經刪除了使用Exporter。這裏沒有必要 - 一個包中定義的所有方法都可以在沒有其參與的情況下通過名稱來調用。

  2. new方法WWW::Foo在其創建的對象上設置account_name鍵,而不是在包本身上。 (包裝上的設置,這將意味着所有對象這裏有同樣的價值,使他們完全沒有用處。)

  3. WWW::Foo::Bar對象現在使用base包從WWW::Foo繼承。

  4. WWW::Foo::Bar::print_name方法現在充實了。我們可以訪問對象上的account_name鍵來獲取名稱。 (這也可以寫成單行print "Hello $self->{account_name}\n",但這不太清楚。)

  5. main包已聲明。 (這只是爲了簡單起見。如果你在自己的文件中寫入每個包你不需要這個。)

  6. 我們實例WWW::Foo::Bar而非WWW::Foo,因爲我們需要的是關於兒童類中定義的方法。 (如果我們實例化父類WWW::Foo,它將不支持此方法。)

  7. 我們不使用間接方法調用new。間接方法調用是不好的。

  8. 我們稱之爲$foo->print_name()來調用該方法。

1

你只是缺少use base在你的孩子班級(package WWW::Foo::Bar

use base qw(WWW::Foo); 
4

你的「兒童」例如包括這一行:

our %EXPORT_TAGS = ('all' => [ qw(new) ]); 

這將導出一個名爲「新」功能並不會出口任何其他功能(例如:print_name)。

然而導出函數是那種「老派」和一些我在Perl代碼幾乎沒有做任何更多的。特別是,如果您正在編寫面向對象的代碼(您似乎是這樣),則不需要導出任何內容,因爲構造函數將通過類名顯式調用,並且所有其他方法都通過對象調用,所以Perl的知道找他們其中包

你調用構造函數是這樣的:

my $foo = new WWW::Foo(); 

它被認爲更好的做法是避免「間接對象語法」,而是明確地調用新的一類方法像這樣:

my $foo = WWW::Foo->new(); 

如果你已經離開了Perl一段時間並想要做OO代碼,我真的建議看看Moose。 Moose::Manual一個很好的起點。