我正在创建一组小型Perl程序,它们将像CLI一样运行。我希望他们所有人分享一些功能,例如。相同的输入/输出格式(可能是JSON)。我还希望每个组件都可以使用模拟参数进行黑盒测试。这就是我到目前为止所做的:
许多模块actionA.pm
,actionB.pm
... actionZZZ.pm
,每个模块/操作一个。所有这些都将use Moose
并且应该有一个sub run {...}
,它将接收带有操作输入参数的数据hasref / object,以及他们需要使用的任何句柄(数据库,文件系统,等等) ,并使用操作的输出参数返回数据hashref / object。
每个requires 'run'
模块actionX.pm
消耗的Moose角色,迫使他们实施run
。
actionX.pm
模块的某些子集的其他Moose角色和/或超类,因此他们可以使用它们来指定他们需要为run
方法提供数据库处理程序,
一个常见的Moose超类(不知道这真的需要是Moose还是超类,只是希望每个actionX.pm
都有一个相当简单的单行),让& #39; s称之为abstractAction.pm
,用于所有actionX.pm
类,它们将它们转换为某种Modulino(见下文)。
我想要实现的是,当我从命令行运行perl actionX.pm arguments
时,abstractAction.pm
中的一些代码将会:
从@ARGV
读取JSON /的任何内容,并将其转换为Perl数据结构。
这一部分不清楚:知道它是从/ actionX
调用的,因此它知道如果actionX
消耗角色needDB
,则需要获取数据库处理程序将其传递给run
等
调用actionX->run()
传递数据对象和在步骤2获得的任何处理程序。
我尝试在run()
中同时使用__PACKAGE__->run()
和abstractAction.pm
,但它调用的是超类方法,而不是孩子的方法。有什么方法可以从父母那里知道孩子的包裹名称吗?这听起来并不好。有没有更好的方法来实现我想要实现的目标?
我知道我可以简单地perl abstractAction.pm actionX arguments
代替perl actionX.pm arguments
并将其称为一天,但我不愿意。
答案 0 :(得分:1)
从根本上说,您需要使用子类的名称(如果它是类方法)或子类的对象(如果它&#)来调用run
作为方法39; s实例方法)作为调用者。
将run
称为类方法:
ActionX->run(...)
将run
作为实例方法调用:
ActionX->new(...)->run(...)
另一个问题是您正在执行.pm
文件,这会导致问题。加载模块,不执行它们。例如,
#!/usr/bin/perl
use strict;
use warnings;
my $action = shift(@ARGV)
or die("usage\n");
$action =~ /^\w+\z/
or die("Bad action\n");
my $pkg = $action; # Or: my $pkg = "...::" . $action;
my $module =~ s{::}{/}g . '.pm';
require $module;
$pkg->new(@ARGV)->run();
如果脚本名为action
,则可以执行
action ActionX parameters