【问题标题】:How to call a class:method determined at runtime in perl?如何调用一个类:在perl中运行时确定的方法?
【发布时间】:2012-10-14 13:12:36
【问题描述】:

我正在尝试制作一个包含大量 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 方法是类方法,继承不太明显。有人可以给建议吗?蒂亚!

【问题讨论】:

    标签: perl class inheritance oop


    【解决方案1】:

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

    package Stuff::Yeah;
    
    sub whatever {
      print "yes\n";
    }
    
    package main;
    
    my $package = "Stuff::Yeah";
    $package->whatever;
    

    【讨论】:

    • 或使用引号:"Model::$package"->load($id);
    【解决方案2】:
    die unless $package =~ /\A\w+\Z/;
    eval "require Model::$package" or die $@;
    $obj1 = "Model::$package"->load($id);
    

    【讨论】:

      【解决方案3】:

      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);
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-11
        • 1970-01-01
        • 1970-01-01
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2012-08-21
        相关资源
        最近更新 更多