2

处理相互使用的模块的最佳方法是什么?

假设我有一个具有哈希函数的模块:

# Really::Useful::Functions::On::Hash.pm

use base qw<Exporter>;
use strict;
use warnings;

use Really::Useful::Functions::On::List qw<transform_list>;

our @EXPORT_OK = qw<transform_hash transform_hash_as_list ...>;

#...
sub transform_hash { ... }

#...
sub transform_hash_as_list {
    return transform_list( %{ shift() } );
}
#...
1

另一个模块已被分割为列表:

# Really::Useful::Functions::On::List.pm

use base qw<Exporter>;
use strict;
use warnings;

use Really::Useful::Functions::On::Hash qw<transform_hash>;

our @EXPORT_OK = qw<transform_list some_func ...>;

#...
sub transform_list { ... }

#...
sub some_func { 
    my %params = transform_hash @_;
    #...
}

#...
1

假设有足够多的实用函数足够方便,我想在 BEGIN 语句和导入函数中使用它们来处理参数列表或配置数据。

我一直在将子定义放入 BEGIN 块中,以确保无论何时有人包含该模块,它们都可以使用。但是我遇到了毛茸茸的竞争条件,在 BEGIN 块中没有完成定义。

我将不断发展的代码习语放入模块中,以便我可以重复使用我发现自己一遍又一遍地编码的任何习语。例如:

sub list_if { 
    my $condition = shift;
    return unless $condition;
    my $more_args = scalar @_;
    my $arg_list  = @_ > 1 ? \@_ : @_ ? shift : $condition;
    if (( reftype( $arg_list ) || '' ) eq 'ARRAY' ) { 
        return wantarray ? @$arg_list : $arg_list;
    }
    elsif ( $more_args ) { 
        return $arg_list;
    }
    return; 
}

捕捉到两个我厌倦了打字的习语:

@{ func_I_hope_returns_a_listref() || [] }

( $condition ? LIST : ())

我在 BEGIN 块中定义的函数越多,我就越有可能使用这些成语积木来表达逻辑,就越有可能在 BEGIN 块中需要积木。

人们有处理这种语言成语砖模型的标准方法吗?

我一直在做的主要是 Pure-Perl;XS会减轻一些吗?

4

3 回答 3

5

如果你想拥有相互依赖的模块,一个简单的方法是使用具有完全限定名称的后期绑定子例程调用(换句话说,在子调用上使用括号)。Prototypes 不会工作,但是 perlSomepackage::mysub()在你真正尝试调用它之前不会关心它没有定义。当我编写相互依赖的模块时,我通常将它们保存在同一个文件中,通过完全避免导入来简化情况。

此外,不需要在 BEGIN 块中定义 sub,因为sub name {...}它与BEGIN {*name = sub {...}}

于 2010-06-16T16:50:37.463 回答
3

您可以有两个模块,每个模块都调用另一个模块,因为这些调用是在运行时完成的,到那时“一切”都将被加载。但是,(显然)这意味着您需要在不崩溃的情况下进入运行时阶段。一种常见的方法是在这两个模块之前包含一些其他模块,use它们都是。作为删除直接use语句的直接结果,您将丢失这些导入,但是将符号从一个模块导入另一个模块并不是一个好主意。

查看您编写的代码,我很惊讶您提出了如此多的“新”处理数据的方法,以至于您觉得有必要将它们提取到单独的库中。你看过标准库Hash::UtilList::UtilList::MoreUtils吗?我建议您使用标准库以更惯用的 Perlish 方式退出您的库和代码。

于 2010-06-16T16:20:00.850 回答
3

如果两个模块相互依赖,那么设计就会出现问题。如果我是你,我会考虑重构我的模块。

于 2010-06-16T15:37:08.827 回答