perl - 设置 Perl 模块结构

标签 perl oop perl-module

我无法弄清楚如何以面向对象的方式构建 Perl 模块,因此我可以拥有一个带有多个子模块的父模块,并且只有需要的特定子模块才会由调用脚本加载。例如,我希望能够像这样进行方法调用:

use Example::API;    
my $api = Example::API->new();

my $user = {};
$user->{'id'} = '12345';

$api->Authenticate();
$user->{'info'} = $api->Users->Get($user->{'id'});
$user->{'friends'} = $api->Friends->Get($user->{'id'});

在文件结构方面,我希望将模块设置如下或以使一切正常工作所需的任何结构:
api.pm
users.pm
friends.pm
...

我首先要这样做的原因是,如果有人只想对 API 进行身份验证,他们不必加载所有其他模块。同样,如果某人只是想获取用户的信息,他们不必加载friends.pm 模块,只需加载users.pm 即可。 .如果您能提供必要的示例 Perl 代码来设置每个模块并解释如何设置文件结构,我将不胜感激。如果我要完成这一切都错了,以完成我要完成的工作,我将不胜感激对最佳方法的解释以及有关如何设置的一些示例代码。

最佳答案

从您的示例中,在您的主模块中,我假设您将提供访问子类的访问器方法。所以你所要做的就是包括require Sub::Module;在该方法的顶部。编译时什么都不会发生,但是第一次运行代码时,perl 会加载模块。第一次加载后,require Sub::Module; 行将成为无操作。

如果您的所有代码都是面向对象的,则您无需担心导入函数。但如果你这样做,声明 use Module qw(a b c);被解释为:

BEGIN {
    require Module;
    Module->import(qw(a b c));
}
BEGIN使它在编译时发生,但没有什么能阻止您在运行时使用内部结构。您在运行时导入的任何子例程都必须用括号调用,并且原型(prototype)将不起作用,因此除非您知道自己在做什么,否则运行时导入可能不是一个好主意。运行时 require s 和通过包方法访问是完全安全的。

所以你的$api->Users方法可能会像这样工作:
# in package 'Example::API' in the file 'Example/API.pm'

sub Users {
    require Example::API::Users;  # loads the file 'Example/API/Users.pm'
    return  Example::API::Users->new( @_ ); # or any other arguments
}

在我上面的例子中,我展示了包名和它们所在的文件之间的两种翻译。一般来说,所有 ::改为/.pm被添加到末尾。然后 perl 将在全局变量 @INC 的所有目录中搜索该文件。 .您可以查看 require 的文档所有的细节。

更新:

缓存此方法的一种方法是在运行时将其替换为仅返回值的函数:
sub Users {
    require Example::API::Users;
    my $users = Example::API::Users->new;

    no warnings 'redefine';
    *Users = sub {$users};

    $users
}

关于perl - 设置 Perl 模块结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3592877/

相关文章:

perl - 为什么每个 perl 包末尾的 1 ?

php - 启用 OCS Inventory WebService 接口(interface)以查询 Assets 数据

Perl - HTTP::Proxy 捕获 XHR/JSON 通信

java - 循环内的 Getter 在赋值后返回 null

javascript - 如何按共同特征组织数据?

perl - 从 Perl 模块导出所有常量(只读变量)的最有效方法是什么

perl - 设置不活动超时 Perl (Mojo) 子进程

perl - 在程序中使用 __DATA__

perl - 如何在 perl 中使用给定的 'OR'?

C# 主窗体实现接口(interface)