2014-04-24 32 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;