2

我正在尝试制作一个包含大量 crud 操作的 crm 应用程序。所以我有控制器类,比如

CRM::Cities
CRM::Countries

不,我使用 ORLite 作为轻量级 ORM。它像这样创建-on the fly-类

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 方法是类方法,继承不太明显。有人可以给建议吗?蒂亚!

4

3 回答 3

4

只需将整个包名,例如Model::Cities,放入变量中。例如:

package Stuff::Yeah;

sub whatever {
  print "yes\n";
}

package main;

my $package = "Stuff::Yeah";
$package->whatever;
于 2012-10-14T13:57:41.633 回答
0
die unless $package =~ /\A\w+\Z/;
eval "require Model::$package" or die $@;
$obj1 = "Model::$package"->load($id);
于 2012-10-14T18:08:21.580 回答
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);

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

于 2012-10-15T16:16:20.270 回答