2

私は多くのcrudアクションを備えたcrmアプリケーションを作成しようとしています. だから私は次のようなコントローラークラスを持っています

CRM::Cities
CRM::Countries

いいえ、軽量 ORM として ORLite を使用しています。そのようなクラスをオンザフライで作成します

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 パッケージごとに 1 つのモデルという考えに固執するのを避けるために、もう 1 つの抽象化レイヤーをお勧めします。

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

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

その後

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

. このように、継承クラスの 1 つがそのモデル クラスがどうあるべきかについて独自のアイデアを開発した場合 (そしてこれが発生した場合)、コードを変更する必要はありません。

于 2012-10-15T16:16:20.270 に答える