perl模块(创建模块,加载模块详解)

如何创建和加载perl模块,深入理解perl模块

加载模块

模块有两种类型:传统模块面向对象模块
传统模块定义子例程和变量,供调用者导入和使用。
面向对象模块相当于类定义,可以通过方法调用来访问。

通过如下命令加载模块:

1.1 编译阶段加载模块使用use

    use MODULE;

等价于:

    BEGIN {
        require MODULE;
        MODULE->import();
    }

有些模块在其导入列表中提供了额外的功能,这个列表将成为import的参数表。

    use MODULE LIST;

相当于:

    BEGIN {
        require MODULE;
        MODULE->import(LIST);
    }

use查询模块的过程

  • 加载模块发生在编译阶段,所以模块中的所有代码都在编译阶段运行。
  • use::转换为/,以MODULE为文件名在末尾追加.pm
  • @INC中查找这个组合成的模块文件。
  • 一旦加载,被找到的文件路径会存入%INC,之后可以重用。
  • 所以,对@INC的所有修改要在use之前发生,

import的使用

  • import把符号(子例程和变量)放在当前命名空间中,从而使编译单元的其余部分可以访问这些符号。
  • 导入默认列表
    use File::Basename;
  • 导入指定符号
    use Hash::Util qw(lock_keys);
  • 不希望任何导入
    use MODULE ();
  • 使用一个模块的某个特定版本(或更新版本)
    use MODULE VERSION LIST;
    ## 正常情况下,任何大于或等于VERSION的版本都是可以的,不能指定版本或版本范围。
    ## 通常指定版本(或更新版本)是为了避免之前版本中的已知的问题。

1.2 运行阶段加载模块使用require

如果希望在运行阶段加载模块,即直到运行一个真正需要这个模块的子例程时才包含该模块,这种情况使用require

    require MODULE;

require也可以直接加载文件,要使用正确的路径分隔符(导致问题:不可移植)

    require FILE;
    require 'Animal/Mammal/HoneyBadger.pm';

1.3 使用no

use反过来就是no。no调用unimport。语法和use一样

no MODULE;
no MODULE LIST;
no MODULE VERSION;
no MODULE VERSION LIST;

no一般用于临时性的目的,比如短时间希望某些符号能够使用,或者短时间不需要某些特性。

## 先使用Moose模块建立对象,在package末尾取消Moose的导入
package Person;
use Moose;
has "first_name" => (is => "rw", isa => "Str");
has "last_name" => (is => "rw", isa => "Str");
sub full_name {
my $self = shift;
$self–>first_name . " " . $self–>last_name
}
no Moose; # keywords are removed from the Person package

or

## 使用符号引用的特性
$a = "this is a";
{
    no strict "refs";
    print ${"a"};
}

创建模块

2.1 命名规则

NOTE:

  • 一旦选择了一个模块名,就不能更换,毕竟不能让用户更新代码去更新模块名。
  • 模块名应当首字母大写。program才能使用全部小写的名字。

2.2 创建传统模块

package Proj_utils 1.001;           ##包名和版本

require Exporter;                   ## 引入Exporter模块
our @ISA = qw(Exporter);            ## 继承Exporter模块

@EXPORT = qw(&getString &getMode);          ## 默认导出的模块
@EXPORT_OK = qw($string $mode);             ## 可以根据请求导出的模块
%EXPORT_TAGS = (                            ## 可以作为标签组导出的模块
        string => [qw($string &getString)],
        mode => [qw($mode &getMode)],
    );
our $string = "this is a module";
sub getString {
    return $string;
}
our $mode = "traditional mode";
sub getMode {
    return $mode;
}

1;

2.3 创建面向对象模块

面向对象的模块规则比较简单,它与用户的通信不多,只要定义好一个对象就行。

package Proj_utils 1.002;

sub new {                   ## 定义一个对象
    my ($class, @args) = @_;
    my $self = {
        string => "this is a oo module",
        mode => "oo",
    };
    bless $self, $class;
}

sub getString {              ## 对象方法
    my $class = shift;
    $class->{string};
}

sub getMode {                ## 对象方法
    my $class = shift;
    $class->{mode};
}

1;

2.4 模块的导出规则

用use加载一个模块时,这个模块通常会提供一些变量或函数允许你的程序访问。
这种从模块导出符号的行为(导入到程序),被称为polluting命名空间。
大多数模块使用Exporter模块完成这个工作。


package A;

## 大多数模块的开头(结合加载模块一节理解'import'函数的作用)
require Exporter;                   ## 加载Exporter模块
@ISA = qw (Exporter);               ## 继承Exporter,获取'import'方法
############或者这样的开头
####    use Exporter qw(import);    ## 获取'import'方法
####
############或者这样的开头
####    @ISA = qw(Exporter)                 ## 必须继承Exporter
####    sub import {                        ## 重写import
####        A->export_to_level(1, @_);      ## 使用export_to_level手动实现import功能
####    }
############################

######### 定义函数和变量
sub func {}
sub func_sm {}

our @arr = qw(a b c);
our $variable = "a variable";

###### 导出符号
@EXPORT = qw(&func $variable);     ## 默认导出
@EXPORT_OK = qw(@arr &func_sm);     ## 根据请求导出
%EXPORT_TAGS = (                    ## 作为标签组导出
    var => [qw($variable @arr)],
    fun => [qw(&func &func_sm)],
);

1

2.5 版本检查

在模块中定义$VERSION变量来定义模块的版本,使用模块的程序就可以确保这个模块足够新。

use Module 3.14;            ## 3.14或更新
use Module v3.0.4;          ## 3.0.4或更新

使用VERSION()查看模块的版本,此函数继承自UNIVERSAL。

print Module->VERSION();

在模块中定义版本

package Module;
our $VERSION = '1.0.1';

或者

package Module v1.0.1;
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值