我有一个名为 Question 的类,以及一堆取决于问题类型的子类。我可以针对子类创建对象,但我不应该能够创建类 Question 本身的对象:
#! /usr/bin/env perl
use strict;
use warnings;
#
# LOAD IN YOUR QUESTIONS HERE
#
my @list_of_questions;
for my $question_type qw(Science Math English Dumb) {
my $class = "Question::$question_type";
my $question = $class->new;
push @list_of_questions, $question;
}
package Question;
use Carp;
sub new {
my $class = shift;
my $self = {};
if ( $class = eq "Question" ) {
carp qq(Need to make object a sub-class of "Question");
return;
}
bless $self, $class;
return $self;
}
yadda, yadda, yadda...
package Question::Math;
use parent qw(Question);
yadda, yadda, yadda...
package Question::Science;
use parent qw(Question);
yadda, yadda, yadda...
package Question::English;
use parent qw(Question);
yadda, yadda, yadda...
请注意,这些不是模块,而只是我定义的要在我的程序中使用的类。因此,我无法在运行时测试模块加载。
当我运行上述内容时,我得到:
Can't locate object method "new" via package "Question::Dumb" (perhaps you forgot to load "Question::Dumb"?)
有什么办法可以捕捉到这个特定的错误,所以我可以自己处理吗?我知道我可以创建一个有效类型的数组,但我希望能够以某种方式添加新的问题类型,而不必记住更新我的数组。
最佳答案
AFAICT 您想要做的是检查符号表以查看您的“类”(又名“包”)是否已定义。手动操作并不困难,但是 Class::Load 提供了更易读的糖并应用了“启发式”——不管这意味着什么。如果您不想使用此模块,那么 is_class_loaded 的源代码将引导您找到您实际寻求的任何答案。
use Class::Load qw(is_class_loaded);
for my $question_type (qw(Math English Science Dumb)) {
my $class = "Question::$question_type";
if(!is_class_loaded($class)) {
# construct your new package at runtime, then
}
new_question($class);
}
你的变量名(“class_type”)很奇怪,所以我修复了它。我也不知道 Module::Load 是否更好,但我们在工作中使用 Class::Load 。
编辑:裸 qw()s 在较新的 Perls 之一(5.14?)中已被弃用。这是一个愚蠢的弃用,但它就在那里,所以我们现在都必须学会将我们的 qw() foreachs 包装在括号中。
关于Perl:测试类是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14324453/