Perl包概念解析

 

本文和大家重点讨论一下Perl包的概念,Perl程序把变量和子程序的名称存贮到符号表中,perl的符号表中名字的集合就称为Perl包(package)。

 

Perl包

Perl程序把变量和子程序的名称存贮到符号表中,perl的符号表中名字的集合就称为Perl包(package)。

1、Perl包的定义

在一个程序中可以定义多个Perl包,每个Perl包有一个单独的符号表,定义语法为:
packagemypack;
此语句定义一个名为mypack的Perl包,从此以后定义的所有变量和子程序的名字都存贮在该Perl包关联的符号表中,直到遇到另一个package语句为止。
每个符号表有其自己的一组变量、子程序名,各组名字是不相关的,因此可以在不同的Perl包中使用相同的变量名,而代表的是不同的变量。如:

$var=14;
packagemypack;
$var=6;
第一个语句创建变量$var并存贮在main符号表中,第三个语句创建另一个同名变量$var并存贮在mypackPerl包的符号表中。

2、在Perl包间切换

在程序里可以随时在Perl包间来回切换,如:

 
 
 
  1. 1:#!/usr/local/bin/perl  
  2. 2:  
  3. 3:packagepack1;  
  4. 4:$var=26;  
  5. 5:packagepack2;  
  6. 6:$var=34;  
  7. 7:packagepack1;  
  8. 8:print("$var\n");  

运行结果如下:

$program
26
$
第三行定义了Perl包pack1,第四行创建变量$var,存贮在Perl包pack1的符号表中,第五行定义新Perl包pack2,第六行创建另一个变量$var,存贮在Perl包pack2的符号表中。这样就有两个独立的$var,分别存贮在不同的Perl包中。第七行又指定pack1为当前Perl包,因为Perl包pack1已经定义,这样,所有变量和子程序的定义和调用都为该Perl包的符号表中存贮的名字。因此第八行对$var的调用为pack1Perl包中的$var,其值为26。

3、mainPerl包

存贮变量和子程序的名字的缺省符号表是与名为main的Perl包相关联的。如果在程序里定义了其它的Perl包,当你想切换回去使用缺省的符号表,可以重新指定mainPerl包:
packagemain;
这样,接下来的程序就好象从没定义过Perl包一样,变量和子程序的名字象通常那样存贮。

4、Perl包的引用

在一个Perl包中可以引用其它Perl包中的变量或子程序,方法是在变量名前面加上Perl包名和一个单引号,如:

 
 
 
  1. packagemypack;  
  2. $var=26;  
  3. packagemain;  
  4. print("$mypack'var\n");  

这里,$mypack'var为mypackPerl包中的变量$var。
注意:在Perl5中,Perl包名和变量名用双冒号隔开,即$mypack::var。单引号引用的方式仍然支持,但将来的版本中未必支持。

5、指定无当前Perl包

在Perl5中,可以用如下语句指定无当前Perl包:
package;
这时,所有的变量必须明确指出所属Perl包名,否则就无效--错误。
$mypack::var=21;#ok
$var=21;#error-nocurrentpackage
这种情况直到用package语句指定当前Perl包为止。

6、Perl包和子程序

Perl包的定义影响到程序中的所有语句,Perl包括子程序,如:

 
 
 
  1. packagemypack;  
  2. subroutinemysub{  
  3. local($myvar);  
  4. #stuffgoeshere  
  5. }  

这里,mysub和myvar都是Perl包mypack的一部分。在Perl包mypack外调用子程序mysub,则要指定Perl包:$mypack'mysub。
可以在子程序中切换Perl包: 

 
 
 
  1. packagepack1;  
  2. subroutinemysub{  
  3. $var1=1;  
  4. packagepack2;  
  5. $var1=2;  
  6. }  

这段代码创建了两个变量$var1,一个在Perl包pack1中,一个在Perl包pack2中,Perl包中的局域变量只能在其定义的子程序等语句块中使用,像普通的局域变量一样。

7、用Perl包定义私有数据

Perl包最通常的用途是用在含有子程序和子程序所使用的全局变量的文件中,为子程序定义这样的Perl包,可以保证子程序使用的全局变量不可在其它地方使用,这样的数据即为私有数据。更进一步,可以保证Perl包名不可在其它地方使用。私有数据例:

 
 
 
  1. 1:packageprivpack;  
  2. 2:$valtoprint=46;  
  3. 3:  
  4. 4:packagemain;  
  5. 5:#Thisfunctionisthelinktotheoutsideworld.  
  6. 6:subprintval{  
  7. 7:&privpack'printval();  
  8. 8:}  
  9. 9:  
  10. 10:packageprivpack;  
  11. 11:subprintval{  
  12. 12:print("$valtoprint\n");  
  13. 13:}  
  14. 14:  
  15. 15:packagemain;  
  16. 16:1;#returnvalueforrequire  

此子程序只有在调用printval后才能产生输出。
该文件分为两个部分:与外界联系的部分和私有部分。前者为缺省的mainPerl包,后者为Perl包privpack。第6~8行定义的子程序printval可被其它程序或子程序调用。printval输出变量$valtoprint的值,此变量仅在Perl包privpack中定义和使用。第15、16行确保其被其它程序用require语句Perl包含后工作正常,15行将当前Perl包设置回缺省Perl包main,16行返回非零值使require不报错。

8、Perl包和系统变量

下列变量即使从其它Perl包中调用,也在mainPerl包中起作用:

文件变量STDIN,STDOUT,STDERR和ARGV
变量%ENV,%INC,@INC,$ARGV和@ARGV
其它含有特殊字符的系统变量

9、访问符号表

在程序中查找符号表可用数组%_package,此处package为想访问的符号表所属的Perl包名。例如%_main含有缺省的符号表。
通常不需要亲自查找符号表。

【编辑推荐】

  1. 学习笔记 Perl包概述
  2. Perl文件句柄概念详解
  3. 实例解析Perl守护进程用法
  4. Perl模式匹配经验总结
  5. 术语汇编 Perl变量中Perl关联数组用法解析
免责声明:文章内容不代表本站立场,仅供读者参考。产品相关技术问题请发送工单。 本文链接:https://www.idc.net/help/395081/

为您推荐

开源数据收集引擎 Logstash 讲解和示例讲解

一、概述 Logstash 是一个开源的数据收集和日志处理工具,它是 Elastic Stack(ELK Stack)的一部分,用于从各种数据源中采集、转换和传输数据,以帮助分析和可视化大规模数据。Logstash 通常与 Elasticsearch 和 Ki...

八个开源免费单点登录(SSO)系统

单点登录(SSO)是一个登录服务层,通过一次登录访问多个应用。使用SSO服务可以提高多系统使用的用户体验和安全性,用户不必记忆多个密码、不必多次登录浪费时间。 下面推荐一些市场上最好的开源SSO系统,可作为商业SSO替代。 1.Authelia https://github.com/authelia/authelia ...

浅谈HBase数据结构和系统架构

Part 01 LSM树模型 常见的的关系型数据库,如MySQL、SQL Server、Oracle等,使用B+ Tree作为数据存储与索引的基本结构,非叶子节点只存放索引数据,叶子节点存放所有数据和指向相邻节点的指针,具有高效的范围查询和稳定的查找效率,以及具有较小的读放大和空间放大。采用磁盘随机读写方式,且以磁盘数...

微软Radius平台重构现代应用程序部署

微软的 Azure 孵化团队日前推出一个叫 Radius 的新应用平台。Radius 平台可用于在 Kubernetes、公共云和边缘环境中运行各种现代应用程序。 Radius 是一个开源项目,最初支持的应用程序运行时包括Kubernetes、Azure和AWS,以后还会支持诸如谷歌云平台等云环境。 Mark Russ...

Ext JS3.0正式版发布

Ext JS3.0在经历数次RC版之后,extjs.com终于发布3.0的正式版。总体而言,较2.0改进不大,依然还是原理的组件模型,具体更新及改进如下: ◆提供了参照DWR后与后台的通讯包Direct,支持具有明显的REST风格的CRUD服务 ◆一系列的新的组件和例子,包括有图表(Charting, By YUI F...
返回顶部