我正在尝试使用基本模块“Apps”构建一个小型应用程序,并在“View”和“Request”等所有模块中共享实例模块“Shared”,以便“共享”模块中的所有数据和方法都可供所有人使用扩展它的其他模块(View,Request,Apps)相同的实例,下面是代码示例。
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
因此,不会反映或与View和其他模块共享对共享模块的更改。 如何使对象的一个实例在所有扩展类之间共享。
我的目标是使所有包在Shared包上扩展,并且该包应该在所有扩展中共享相同的实例数据。
答案 0 :(得分:1)
Shared
不应该是所有对象都从中继承的基类。 Shared
类应该与继承的观点完全分开。
相反,每个类都应该有一个属性(这可能是一个私有的属性,称为以下划线开头的隐藏),指向Shared
类的共享对象。当一个对象创建另一个对象时(在您的示例中,$ app对象创建一个$ view对象),它可以为新对象分配一个指向其Shared
类实例的指针。
这样的事情:
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;