2014-04-24 34 views
1

我試圖在所有模塊(如「查看」和「請求」)之間構建一個包含基本模塊「應用程序」和共享實例模塊「共享」的小應用程序,以便「共享」模塊中的所有數據和方法可用於擴展它的所有其他模塊(查看,請求,應用程序)相同的實例,下面是代碼示例。Perl繼承相同的實例

app.cgi

#!/usr/bin/perl 

use Moose; 
use Apps; 

my $app = Apps->new; 

msg(); # exported, works ok 
$app->msg(); # as method works ok 

my $view = $app->view; 
$view->msg; # view class method, works ok 

print $app->charset . "\n"; # from Shared.pm, prints utf8, default 
$app->charset("windows-1256"); # change from utf8 to windows-1256 in Shared.pm 
print $app->charset . "\n"; # this now ok, prints windows-1256 
print $view->charset . "\n"; # this is not ok, the same default utf8 

exit; 

Apps.pm

package Apps; 
use Moose; 
extends qw(Shared); 
sub init { 
    print "true is: " . true()."\n"; 
} 
1; 

View.pm

package View; 
use Moose; 
extends qw(Shared); 
sub msg { 
    print "Hello msg from View\n"; 
} 
1; 

Request.pm

package Request; 
use Moose; 
extends qw(Shared); 
sub msg { 
    print "Hello msg from request\n"; 
} 
1; 

當我運行app.cgi我得到這個輸出:

Hello msg from Shared 
Hello msg from Shared 
Hello msg from View 
utf8 
windows-1256 
utf8 

我所期待的是:

Hello msg from Shared 
Hello msg from Shared 
Hello msg from View 
utf8 
windows-1256 
windows-1256 

所以更改共享模塊沒有反映或與視圖和其他模塊共享。 如何使所有擴展類共享對象的一個​​實例。

我的目標是讓所有包都在共享包上進行擴展,並且該包應該在所有擴展之間共享相同的實例數據。

+1

可能重複http://stackoverflow.com/questions/6862387/how-to-share-an-attribute-between-multiple-moose-objects – KeepCalmAndCarryOn

回答

1

Shared不應該是所有對象繼承的基類。 Shared類應該與繼承的觀點完全分開。

相反,每個類都應該有一個屬性(這可能是一個私人的屬性,以一個下劃線開頭,稱爲模糊的東西),它指向Shared類中的共享對象。當一個對象創建另一個對象時(在你的例子中,$ app對象創建一個$ view對象),它可以爲新對象指定一個指向其類實例的指針。

事情是這樣的:

use v5.14; 

package Shared { 
    use Moose; 
    has foo => (is => 'rw', default => 99); 
    has bar => (is => 'rw', default => 42); 
} 

package App { 
    use Moose; 
    has _common => (
     is  => 'ro', 
     default => sub { Shared->new }, 
     handles => [qw/ foo bar /], 
    ); 
    sub view { 
     my $self = shift; 
     View->new(@_, _common => $self->_common); 
    } 
} 

package View { 
    use Moose; 
    has _common => (
     is  => 'ro', 
     required => 1, 
     handles => [qw/ foo bar /], 
    ); 
} 

my $app = App->new; 
my $view = $app->view; 

say '$app->foo : ', $app->foo; 
say '$view->foo : ', $view->foo; 

# change the value of $app->foo. 
# this will be shared with $view. 
$app->foo(66); 

say '$app->foo : ', $app->foo; 
say '$view->foo : ', $view->foo;