Perl 什么';处理相互使用的模块的最佳方式是什么?

Perl 什么';处理相互使用的模块的最佳方式是什么?,perl,perl-module,Perl,Perl Module,处理相互使用的模块的最佳方式是什么 假设我有一个模块,它有散列函数: # 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_ha

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

假设我有一个模块,它有散列函数:

# 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
捕获了两个我有点厌倦键入的习惯用法:

@{ func_I_hope_returns_a_listref() || [] }

我在BEGIN块中定义的函数越多,就越有可能使用这些习惯用法块来表示逻辑,BEGIN块中就越可能需要这些块

人们是否有处理这种语言习语的标准方法


我一直在做纯Perl;XS会缓解一些问题吗?

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

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


看看您编写的代码,我很惊讶您提出了这么多处理数据的“新”方法,以至于您觉得有必要将这些方法提取到单独的库中。你看过标准库了吗?我建议您从库中退一步,使用标准库以更惯用的Perlish方式编写代码。

如果您想拥有相互依赖的模块,一个简单的方法是使用具有完全限定名的后期绑定子例程调用(换句话说,在子调用中使用paren)。原型不起作用,但是perl不会在意
Somepackage::mysub()
在您实际尝试调用它之前没有定义。当我编写相互依赖的模块时,我通常将它们保存在同一个文件中,这样可以完全避免导入,从而简化情况


此外,不需要在BEGIN块中定义sub,因为无论sub是否在BEGIN块中,sub都是在编译时加载的,因为
sub name{…}
BEGIN{*name=sub{…}}

相同。你能给出一个需要在BEGIN块中定义的函数的例子吗?@mobrule:也许我不需要将它们放在BEGIN块中,但这就是有效的方法,使用补锅匠直到你没有“解决”问题的错误方法。当我试图积累越来越多的习语块来逐步提高编码和测试的速度时,是什么激发了一个长期存在的问题。
List::Util
List::MoreUtils
无疑,但是
Hash::Util
作为哈希的通用实用程序库几乎是无用的,除非您关心的是锁定键和其他一些处理哈希硬结构的事情,而不是它们作为名称-值关联的通用实现的一般抽象。具有讽刺意味的是,我想在CPAN上推出一个通用的哈希实用程序,这部分是促使我关注我的“解决方案”的原因。好吧,导入在OO模块中主要是一个坏主意,因为它们给出了类功能和推断行为的误报。这是一种可能性,但这些不是真正的“设计”元素,而是或多或少的代码习惯用法集合,它们本身在其他代码习惯用法中很有用。
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 : ())