zoukankan      html  css  js  c++  java
  • Perl包相关

    名称冲突问题

    假如在sum2.pm中使用require导入了一个代码文件sum1.pm:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    require '/perlapp/sum1.pm';
    
    sub sum {
        say "sum2: sum()";
    }
    1;
    

    如果在sum1.pm中也有一个sum子程序:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    sub sum {
        say "sum1: sum()";
    }
    1;
    

    那么在运行sum2.pm的时候,将警告子程序重新定义。因为sum2.pm首先编译好自己的sum(),然后在运行期间require导入文件时,又再次定义sum(),将进行覆盖操作:

    Subroutine sum redefined at /perlapp/sum1.pm.....
    

    这样的名称冲突问题,通过声明包来解决。

    定义包和访问包属性

    要定义一个包,只需要加上关键字package即可。

    package PKG_NAME [ VERSION_NUM ];
    

    上面的语句用于声明包,可以带上包版本号,例如package pkg1 0.01;

    例如,在sum1.pm中:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    package Sum1;
    
    sub sum {
        say "pkg:Sum1,sum()";
    }
    1;
    

    然后其它文件导入sum1.pm后,就可以使用包名::属性的方式访问sum1.pm中的属性,如子程序。

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    require '/perlapp/sum1.pm';
    
    sub sum {
        say "file: sum2,sum()";
    }
    
    sum();         # 访问本文件定义的sum子程序
    Sum1::sum();   # 访问包Sum1::sum子程序,括号不能少
    
    1;
    

    除了子程序,包中的其它非词法作用域的属性也能被访问,包括:标量、数组、hash、文件句柄。例如:

    $Sum1::name;
    @Sum1::arr;
    

    每个文件都至少定义在一个包内,如果没有显式给定package指令,则这个包默认为main包。所以,访问本程序文件内自身属性的时候可以使用main:: + 属性的方式。例如在sum2.pm中:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    require '/perlapp/sum1.pm';
    
    sub sum {
        say "file: sum2,sum()";
    }
    
    sum();         # 访问本文件定义的sum子程序
    main::sum();   # 等价于上一行直接访问sum()
    Sum1::sum();   # 访问包Sum1::sum子程序,括号不能少
    
    1;
    

    一个文件内多个包

    一般来说,一个文件只会定义一个包。但允许一个文件定义通过包。

    如下:

    package Pkg1;
    
    ...code here belong to Pkg1...
    
    package Pkg2;
    
    ...code here belong to Pkg2...
    

    定义多个包时,从包1到包2中间的所有属性都属于包1。

    例如,在sum1.pm中:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use 5.010;
    
    sub sum {      # 位于默认的main包
        say "pkg:main,sum()";
    }
    
    package Sum1;  # 第一个包
    
    sub sum {      # 位于Sum1包
        say "pkg:Sum1,sum()";
    }
    
    sum();        # 访问的是Sum1包的sum()
    main::sum();  # 访问的是main包的sum()
    
    package Sum2;   # 第二个包
    
    sub sum {       # 位于Sum2包
        say "pkg:Sum2,sum()";
    }
    
    sum();        # 访问的是Sum2包的sum()
    Sum1::sum();  # 访问的是Sum1包的sum()
    main::sum();  # 访问的是main包的sum()
    
    1;
    

    有一些词语名称总是属于main包的: ARGV、ARGVOUT、ENV、INC、SIG、STDERR、STDIN 以及 STDOUT。有些带有特殊标点符号的名称(如$_,$2, $!),它们也全部属于main。

    另外,词法变量是不能使用包名访问的,因为使用包访问的属性,都是"全局"属性。所以,要在代码块中访问全局属性,可以加上包名:

    package Sum1;
    out $var="1234";
    sub mysub {
        my $var;
        ...$var...;  # 访问的是my $var
        $Sum1::var;  # 访问的是Sum1包中的$var
    }
    

    如果将一个包声明放进代码块,则出了代码块的域后就消失:

    package Sum1;
    
    {
    
        package main;
        sub sum {
            say "in main"
        }
        sum();  # 调用main中的sum
    }  # 退出代码块,重新回到Sum1包
    
    sub sum {code}   # 属于Sum1包的sum子程序
    

    包代码块

    从perl 5.12开始,支持包代码块:

    use v5.12;
    package pkg1 {
        ...
    }
    
    package pkg2 {
        ...
    }
    

    包代码块相当于词法范围:

    package Navigation {
        my @homeport = (21.283, -157.842); # 属于包
        sub get_me_home {
            my @homeport;     # 声明词法变量
            ... @homeport ... # 访问的是词法变量
            ... @Navigation::homeport ... # 访问的是包变量
        }
        ... @homeport ... # 访问的是包变量
    }
    

    它等价于:

    {
        package Navigation;
        my @homeport = (21.283, -157.842); # 属于包
        sub get_me_home {
            my @homeport;     # 声明词法变量
            ... @homeport ... # 访问的是词法变量
            ... @Navigation::homeport ... # 访问的是包变量
        }
        ... @homeport ... # refers to the package variable
    }
    
  • 相关阅读:
    [Everyday Mathematics]20150208
    [Everyday Mathematics]20150207
    [Everyday Mathematics]20150206
    数学基本技艺100题
    这天,白云酒楼里来了两位客人
    [Everyday Mathematics]20150205
    [Everyday Mathematics]20150204
    数学书籍阅读
    国科金发计〔2014〕86号
    [Everyday Mathematics]20150203
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9771806.html
Copyright © 2011-2022 走看看