博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Perl包和模块
阅读量:5334 次
发布时间:2019-06-15

本文共 4402 字,大约阅读时间需要 14 分钟。

符号表

  每个包都有自己的一个符号表,它是一个哈希表;关键字是包中的变量名、文件句柄、目录句柄以及子例程,值是typeglob

每个符号都被赋予一个typeglob(即*x),它表示所有名为x的类型。

  每个包都有自己的符号表。无论何时使用包声明,都要切换到该包的符号表。从一个包中访问另外一个包的变量,可通过“ 包名 + 双冒号( :: ) + 变量名 " 的方式指定。由于 my 函数赋值的变量不能从其所在的包外面访问,而且它也没有存储在包符号表中,而是存储在为每个子程序所创建的缓冲区里。因此,在使用 "my" 变量时,用户无法通过包的符号表来访问它们,因为它们根本不在那里!

require函数

  require 可以导入 Perl 库,然后便可执行其中的例程或代码,它类似于 C 语言中的 #include 。

  使用 require 的格式为:require EXPR 。也可以不带参数,此时该函数导入的就是 $_ 变量值。require 导入的库文件要存在于 @INC 所包含的某个路径之中,否则函数将执行失败,并返回类似于下面的信息:

1 $ ./require.pl2 Can't locate hello.pl in @INC (@INC contains: /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .) at ./require.pl line 3.

测试代码:

1 #!/usr/bin/perl2 require "pwd.pl";3 require "ctime.pl";4 &initpwd;                                   #初始化函数,位于 pwd.pl 中5 printf "The present working directory is %s\n", $ENV{PWD};6 &chdir ("../..");                   #切换目录,该函数位于 pwd.pl 中7 printf "The present working directory is %s\n", $ENV{PWD};8 $today = &ctime(time);        #获取时间,该函数位于 ctime.pl 中9 print "$today";

执行结果:

1 $ ./require.pl2 The present working directory is /home/beyes/perl/package3 The present working directory is /home/beyes

  如果打开 pwd.pl 或 ctime.pl 这样的库文件时,可能会注意到,库文件中的最后一行语句是 " 1; " 。对于 require 函数来说这是必须的,此时 require 函数将不把文件加载到程序中。我们也可以模仿 pwd.pl 的做法编写自己的库,然后放在相应的正确目录下,这样便可以使用自定义的库了。在使用自定义的库时,也不忘记在最后一行写上 "1;" ,否则会在使用 require 时返回类似的错误提示:xxx.pl did not return a true value at xxx.plx lines 5 。

@INC 数组

  @INC 是 Perl 内置的一个特殊数组,它包含指向库例程所在位置的目录路径,如果你包含的库并不在这些目录之下,那么可在命令行中使用 -l 选项开关,这点和 gcc 编译时使用-L和-l选项使用第三方库的行为有些类似。@INC对use命令没用,它只服务于require命令,use命令直接去访问perl模块目录(如/usr/lib/perl5/5.6/)

可以用 perl -V 命令看到 @INC 数组的内容:

1 $perl -V2 ...3   @INC:4     /usr/local/lib/perl55     /usr/local/share/perl56     /usr/lib/perl5/vendor_perl7     /usr/share/perl5/vendor_perl8     /usr/lib/perl59     /usr/share/perl5

perl 命令的 -e 选项可以后接命令,这样可以单独的打印出 @INC 的内容:

1 $ perl -e 'print "@INC\n"'2 /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .

  由上可见,@INC 数组最后一个元素是当前目录,如果我们希望将当前工作目录称为搜索路径中第一个元素,那么可以使用 unshift (@INC, "."); 来完成。

包的概念

  单独的命名空间又称为包 (package) 。单独的命名空间意味着,对于命名包中所有的变量,Perl 都持有一个单独的符号表。默认情况下,包内所有的变量都是全局变量,而包机制则允许用户切换命名空间,从而让保重的变量称为私有变量,即使它们在包外拥有相同的名称也可如此。

包的作用域

  包的作用域从声明位置开始直到文件末尾,或者是最内层封闭块的末尾,还可以是知道另一个包的声明为止。声明另一个包就用 package 函数。在一个包中引用另一个包中的变量,可以在包名前面加上代表变量数据类型的特殊符号,然后是双冒号和变量名,如:$friend::name 。

在Perl包间切换及包的引用:

1 #!/usr/bin/perl 2  3 @town = qw(china wencheng qinglan); 4 $friend = "Jasmine"; 5 #在main包中 6 print "In main: \$friend is $friend\n"; 7 #声明 boy 包,并切换到boy 8 package boy; 9 #$name在boy包中的命名空间里,和main中的互不干扰10 $name = "Tony";11 print "In boy \$name is $name.\n";12 #使用main包中的$friend,并进行修改13 $main::friend = "Obama";14 print "In boy \@town is @::town\n";  #main包是默认包,不需要写出main的名字,用@符号代替main15 #切换回main包中16 package main;17 print "In main: \$name is $name\n";18 print "In main: \$main is $boy::name\n";19 print "In main: \$friend is $friend.\n";

运行结果:

1 In main: $friend is Jasmine2 In boy $name is Tony.3 In boy @town is china wencheng qinglan4 In main: $name is5 In main: $main is Tony6 In main: $friend is Obama.

 

创建一个包及引用包中的子例程

1 #!/usr/bin/perl2 unshift(@INC,"D:\\perlwork1");3 require "average.pl";4 print "Enter your midterm scores\n";5 6 @scores=split(' ',
);7 8 printf "The average is %.lf.\n",average::ave(@scores);#应用包中ave子例程

创建包

1 #!/usr/bin/perl 2 package average 3 sub ave 4 { 5     my (@grades)=@_; 6     my ($num_of_grades)=$#grades+1; 7     foreach $grade( @grades ) 8     { 9         $total +=$grade;10     }11     $total/$num_of_grades;12 }13 1;

模块

  Perl5中用Perl包来创建模块,方法是创建Perl包并将之存在同名的文件中。例如,名为Mymodult的Perl包存贮在文件Mymodult.pm中(扩展名.pm表示PerlModule)。下例的模块Mymodult含有子程序myfunc1和myfunc2及变量$myvar1和$myvar2。

1 #!/usr/bin/perl   2 package  Mymodule;  #定义模块名称 Mymodule.pm 3 require  Exporter;  #使用Exporter.pm模块将本模块符号导出到另一个包(加载者) 4 @ISA=qw(Exporter);  #@ISA数组含有本模块需要用到的包名,本模块用到模块Exporter.pm 5 #@EXPORT列出了从本模块默认导出到模块调用者的子例程。myfunc3不在导出列表(@EXPORT)中,调用者不能直接调用myfunc3。 6 @EXPORT=qw(myfunc1,myfunc2);  7 @EXPORT_OK=qw($myvar1$myvar2);   8    9 sub myfunc110 {  11          $myvar1+=1;  12 }  13   14 sub myfunc215 {  16          $myvar2+=2;  17 }          18 19 sub myfunc320 {  21          $myvar3+=2;  22 }

注:.pm文件不仅放在perl工作库目录,其实放在当前目录,也可以直接use

 

转载于:https://www.cnblogs.com/polestar/archive/2012/05/02/2479252.html

你可能感兴趣的文章
NumPy数值计算(1)
查看>>
图论trainning-part-1 D. Going in Cycle!!
查看>>
POJ 2553 The Bottom of a Graph
查看>>
CSS flex 布局学习笔记
查看>>
hitb2017 sentosa writeup
查看>>
php实现字符串的排列(交换)(递归考虑所有情况)
查看>>
移动开发基础和Dalvik VM
查看>>
2、springboot返回json
查看>>
ZOJ 2083 Win the Game(SG函数)题解
查看>>
HDU 5919 Sequence II(主席树)题解
查看>>
PAT 1029
查看>>
显示服务器上的数据库
查看>>
java基础知识
查看>>
Obsolete此API即将移除
查看>>
登录表单(入门简单)
查看>>
toj 4074 CF 319C 斜率优化dp
查看>>
Java注解之Retention、Documented、Target、Inherited介绍
查看>>
Javascript:谈谈JS的全局变量跟局部变量
查看>>
重温设计模式 - 外观模式
查看>>
oracle数据文件迁移
查看>>