我可以定义一个可以像内置一样调用的子程序吗?

时间:2012-08-15 12:12:36

标签: perl subroutine globals

目前,在调试过程中,我倾向于插入

carp Dumper \@foo, \%bar;

语句到我的代码中,并经常遇到CarpData::Dumper未在当前包中导入的问题。为了避免这个问题,我在一个总是包含的中心文件中定义了以下子:

sub main::bla {
    use Carp; use Data::Dumper;
    carp Dumper @_;
}

所以现在我可以做到

main::bla \@foo, \%bar;

无处不在,但main::让我烦恼。有没有类似全局软件包的东西总是在任何软件包中自动导入(就像内置插件几乎被导入到各处)?

3 个答案:

答案 0 :(得分:4)

你可以称之为

::bla( \@foo, \%bar );

在早些时候,我曾经将util函数放在Ut包中。这很好,但我注意到我的代码并不像我想象的那样模块化。依赖于Ut函数的每个模块只有在有人麻烦地构建该命名空间时才能成功。

最后,我将userequire语句视为仅记录依赖项。有更灵活的方法来更改库模块调用的代码,而不是在main中更改它们的实现。

例如,您可以在单个use语句中执行此操作。

use Ut blah => sub { 
    use Carp; 
    use Data::Dumper;
    carp Dumper @_;
};

并定义导入:

sub import { 
    shift; # It's just me
    my ( $name, $impl ) = @_;
    if ( $name eq 'blah' && ref( $impl ) eq 'CODE' ) { 
        *blah = $_[1];
    }
    ...
}

当我一次开发大量代码时,我仍然使用ut模式。但我不介意写作

ut:dump_var( $var )

而不是保存3-4个字符(因为有时我称之为U::)。

现在,您似乎不想长期这样做,并且转储变量对于开发来说是一件有用的事情。如果你真的想这样做,Smart::Comments会这样做:

### @foo
### %bar

所需要的只是一个使用声明。

use Smart::Comments;

答案 1 :(得分:1)

也许只是更好地制作另一个包含导出和需要的东西? 比如,MyTest.pm:

package MyTest;

use strict;
use Carp;
use Data::Dumper;


use base qw( Exporter );
our @EXPORT = qw(
    debug
)

sub debug {
    carp Dumper @_;
}

1;

所以你可以在你的脚本中写一下:

use MyTest;

debug {a => 'b', c => 'd' }

答案 2 :(得分:0)

有趣的事实:Some symbols是神奇的,因为它们总是在main包中引用它们的值。您可以将子例程分配给这些符号,它们将在任何包中显示。

{
    package Foo;

    # special names _ ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT
    sub ENV { print "In main::ENV ...\n" }
    sub STDIN { print "In main::STDIN ...\n" }
    sub _ { print "In main::_\n" }

    # names that begin with ^ + upper case letter, or all digits
    *{^T} = sub { scalar localtime };
    *{^Gmtime} = sub { scalar gmtime };
    *43 = sub { 42 };

    use Data::Dumper;
    *{^D} = \&Data::Dumper::Dumper;
}

{
    package Bar;
    &ENV;


    STDIN();
    print "The time is ", &^T, "\n";
    print "In London it is ", &{^Gmtime}, "\n";
    print "The answer is ", &43, "\n";

    print "\@foo is ", &^D( \@foo );
}

除非你想让下一个维护你代码的人疯狂,否则不建议这样做。