如何调用类:在运行时在perl中确定的方法?

时间:2012-10-14 13:12:36

标签: perl class inheritance oop

我正在尝试使用大量的crud操作来创建一个crm应用程序。所以我有像

这样的控制器类
CRM::Cities
CRM::Countries

不,我使用ORLite作为轻量级ORM。它创造了像这样的飞行类

Model::Cities
Model::Countries

现在说我要加载一个城市。在CRM :: Cities类中,我必须做类似的事情 (ORLite使用类方法进行访问)

$obj1 = Model::Cities->load($id);

在CRM :: Countries中加载当前国家/地区:

$obj1 = Model::Countries->load($id);

所以我最终在每个控制器类中包含类似的行。

我希望能够做到的是在CRM软件包(基本控制器类)中执行类似这样的通用操作:

$obj1 = Model::$package->load($id);
# package contains Cities or Countries, determined at runtime

我尝试了各种变体,使用eval等等,但这是更高阶的perl。我认为b / c的ORLite方法是类方法,继承不太明显。有人可以给出建议吗? tia!

3 个答案:

答案 0 :(得分:4)

只需输入整个包裹名称,例如Model::Cities,变量。例如:

package Stuff::Yeah;

sub whatever {
  print "yes\n";
}

package main;

my $package = "Stuff::Yeah";
$package->whatever;

答案 1 :(得分:0)

die unless $package =~ /\A\w+\Z/;
eval "require Model::$package" or die $@;
$obj1 = "Model::$package"->load($id);

答案 2 :(得分:0)

Perl允许您将字符串用作类名,因此您可以说

$obj1 = "Model::Cities"->load($id);

或确实

$obj1 = "Model::$package"->load($id);

实际上

my ($package) = $class =~ /([^:]+)$/;
$obj1 = "Model::$package"->load($id);

这是加载内容的一种很好的通用方法,但我建议再使用一层抽象,以避免与一个每个CRM模型包的想法过于结合:

sub _model_class {
    my ($class) = @_;

    my ($package) = $class =~ /([^:]+)$/;
    return "Model::$package";
}

然后

$obj1 = $class->_model_class->load($id);

。这样,如果其中一个继承类开发了自己关于模型类应该是什么的想法(并且发生这种情况),则不需要更改任何代码。