如何将常见参数传递给Perl模块?

时间:2010-05-03 19:22:05

标签: perl module

对于为一些调用各种Hadoop MapReduce作业的脚本开发的(很多)Perl脚本而言,我对于参数传递架构我并不感到兴奋。

目前有8个脚本(形式为run_something.pl)从cron运行。 (还有更多的方法......对于我们添加到hadoop的每个函数,我们预计会增加1到3个。)每个函数都有大约6个相同的命令行参数,以及几个相似的命令行参数,所有这些都是指定的与欧几里德。

实现是在十几个.pm模块中。其中一些很常见,而另一些则是独一无二的......

目前我正在将args全局传递给每个模块......

在run_something.pl里面我有:

set_common_args         (%ARGV);
set_something_args      (%ARGV);

在Something.pm里面,我有

sub set_something_args {     (%MYARGS)= @ _; }

那么我可以做到

if ( $MYARGS{'--needs_more_beer'} ) { 
    $beer++;
}

我看到我可能会有其他“常见”文件,我想将args传递给,所以我会在每个run_something.pl的顶部有三个或四个set_xxx_args调用,并且它似乎并不太优雅。

另一方面,它将整个愚蠢的参数数组传递给调用链,并且选择并向调用链传递单个元素是(a)过多的工作(b)容易出错(c)不买多了。

在很多方面,我所做的只是面向对象的设计而没有面向对象的语言陷阱,而且看起来更加丑陋而没有所谓的陷阱,但是仍然......

任何人都有想法或想法?

2 个答案:

答案 0 :(得分:10)

与Pedro的答案一样,但升级为使用MooseMooseX::Getopt,我向SO社区展示了......一个驼鹿modulino *:一个可以使用的驼鹿模块包含并作为模块正常运行,或作为命令行实用程序单独运行:

# this is all in one file, MyApp/Module/Foo.pm:

package MyApp::Module::Foo;
use Moose;
use MooseX::Getopt;

has [ qw(my config args here) ] => (
    is => 'ro', isa => 'Int',
);

sub run { ... }

package main;
use strict;
use warnings;
sub run
{
    my $module = MyApp::Module::Foo->new_with_options();
    $module->run();
}

run() unless caller();

可以使用以下方法调用模块:

perl MyApp/Module/Foo.pm --my 0 --config 1 --args 2 --here 3

使用此模式,您可以使用一个模块收集命令行参数,该模块由共享相同选项的所有其他模块和脚本use组成,并使用标准Moose访问器方法来检索这些选项。 / p>

* modulinos是也可以作为独立脚本运行的模块 - 由SO自己的brian d foy设计的Perl设计模式。

答案 1 :(得分:4)

查看import中的Getopt::Long。您通过use Module qw/.../将参数传递给模块,并通过import子例程获取它们。

# Override import.                                                                                                                                                                                  
sub import {
    my $pkg = shift;            # package                                                                                                                                                           
    my @syms = ();              # symbols to import                                                                                                                                                 
    my @config = ();            # configuration                                                                                                                                                     
    my $dest = \@syms;          # symbols first                                                                                                                                                     
    for ( @_ ) {
        if ( $_ eq ':config' ) {
            $dest = \@config;   # config next                                                                                                                                                       
            next;
        }
        push(@$dest, $_);       # push                                                                                                                                                              
    }
    # Hide one level and call super.                                                                                                                                                                
    local $Exporter::ExportLevel = 1;
    push(@syms, qw(&GetOptions)) if @syms; # always export GetOptions                                                                                                                               
    $pkg->SUPER::import(@syms);
    # And configure.                                                                                                                                                                                
    Configure(@config) if @config;
}