加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何使用Perl Moose插件作为主要对象?

发布时间:2020-12-16 06:13:04 所属栏目:大数据 来源:网络整理
导读:我是穆斯的新手.我必须创建一个应该加载几个插件的对象.结构是这样的: 主要对象 – 一些通用功能 插件 – 主对象的扩展 插件位于服务器上的单独文件夹中.主对象必须加载插件,初始化它们并将对象存储在自身中.每个插件的返回值必须通过主对象.因为主对象应该
我是穆斯的新手.我必须创建一个应该加载几个插件的对象.结构是这样的:

>主要对象 – >一些通用功能
>插件 – >主对象的扩展

插件位于服务器上的单独文件夹中.主对象必须加载插件,初始化它们并将对象存储在自身中.每个插件的返回值必须通过主对象.因为主对象应该为调用者转换JSON结构中的每个返回值.

我会这样称呼:

my $main_obj = Main->new();
$main_obj->plugin('MainExtention')->get_title();

这是我的示例代码:

主要对象:

package Main;
use Moose;

has 'plugins' => (
    is          => 'rw',);

has 'title' => (
    is          => 'rw',isa         => 'Str',reader  => '_get_title',);

# load plugins
sub _load_modules {
  my $self = shift;

    my $path = "/usr/local/apache/sites/.../Plugins";
  push(@INC,$path);

  my @modules = _find_modules_to_load($path);

  eval { 
        my $plugins = {};
        foreach my $module ( sort @modules) {
            (my $file = $module) =~ s|::|/|g;
            (my $modname = $module) =~ s/.*?(w+$)/$1/;
            require $file . '.pm';
            my $obj = $module->new();
            $plugins->{$modname} = $obj;
            1;
        }
        $self->plugins($plugins);
  } or do {
      my $error = $@;
      warn "Error loading modules: $error" if $error;
  };

}

# read plugins
sub _find_modules_to_load {
    my ($dir) = @_;
    my @files = glob("$dir/*.pm");

    my $namespace = $dir;
    $namespace =~ s///::/g;

    # Get the leaf name and add the System::Module namespace to it
    my @modules = map { s/.*/(.*).pm//g;  "${namespace}::$1"; } @files;

    return @modules;
}

sub BUILD {
    my $self = shift;
    $self->_load_modules();
}

sub get_title {
    return 'main title'
}

1;
__PACKAGE__->meta->make_immutable;

目录“/usr/local/apache/sites/…/Plugins”中的插件MainExtention:

package MainExtention;
use Moose;

has 'title' => (
    is          => 'rw',default     => 'Default',);

sub get_title {
    return 'MainExtention Title';
}

1;

这样工作如下:

my $main = Main->new();
my $plugins = $main->plugins();
print $plugins->{'MainExtention'}->get_title();

但这不是我将拥有的:)我将不是直接从插件返回插件,而是从主对象.有没有人有想法?
第二个问题:是否有更简单的方法来加载插件?怎么样?

解决方法

要加载插件,我建议使用 Module::Pluggable,它可以从目录加载一堆包,并根据需要实例化它们(或不实例化).

如果你需要让主对象包装插件,只需在主对象上定义一个方法来做你需要的任何事情:

package Main;
use Moose;

# Adds a plugins() method to Main that returns a list of all loaded plugin packages
use Module::Pluggable search_dirs => [ "/usr/local/apache/sites/.../Plugins" ];

# Used to store the plugins after ->new is called on each package
has loaded_plugins => (
    is => 'rw',isa => 'HashRef[Object]',lazy_build => 1,traits => [ 'Hash' ],handles => { _plugin => 'get' },);

# Constructor for loaded_plugins,implied by lazy_build => 1
sub _build_loaded_plugins {
    my ($self) = @_;

    my %loaded_plugins;
    for my $plugin ($self->plugins) {
        $loaded_plugins{$plugin} = $plugin->new;
    }

    return %loaded_plugins;
}

# Method for getting the processed title from any plugin
sub get_plugin_title {
    my ($self,$name) = @_;

    my $plugin = $self->_plugin($name);

    my $title = $plugin->get_title;

    # process the title according to whatever Main needs to do...
    ...

    return $title;
}

然后,你的代码:

my $main = Main->new();
print $main->get_plugin_title('MainExtension');

如果您正在使用Moose,我可能还建议您将所有插件实现为role,这可以帮助您发现插件是否已正确实现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读