【发布时间】:2023-03-25 08:45:01
【问题描述】:
我正在开发一个为其“父”包定义异常的包(使用Exception::Class::Nested)。我不希望父包必须使用非常长的名称,但是,并且我不想污染任何其他命名空间。
所以我想做的是将类名的最后一个元素导出到 used 异常包的包的命名空间中。
例如,异常包的摘录:
package Klass:Foo::Bar::Exceptions;
use vars qw( @ISA @EXPORT @EXPORT_OK ... );
@ISA = qw( Klass::Foo::Bar Exporter );
use Exception::Class::Nested 0.04 (
'Klass::Foo::Bar::Exceptions::BaseClass' => {
description => 'Base class for exceptions',
'Klass::Foo::Bar::Exceptions::NameError' => {
error => "I don't like your face"
}
}
);
“父”包:
package Klass::Foo::Bar;
use Klass::Foo::Bar::Exceptions;
Klass::Foo::Bar::Exceptions::NameError->throw(error => "D'oh!");
my $e = NameError->new(error => 'Mwahaha!');
我希望喜欢导出/导入异常类,这样第二次调用(my $e 之一)就好像 NameError 是在 Klass::Foo::Bar 中定义的一样,但我没有还没弄明白。
(在有人说'但Exception::Class 有漂亮的alias 东西'之前,我会指出别名与异常的throw 方法特别相关联,所以我不能将它用于非自动抛出的new 调用......)
我试过的一件事是把它放在异常包的 importer 子中(@snames 是一个完全限定异常类的数组(例如,'Klass::Foo::Bar::Exceptions::NameError'),或者只是尾端(例如,'NameError'):
my $caller = caller();
$caller ||= 'main';
my @snames = @{$EXPORT_TAGS{exceptions}};
for my $exc (@snames) {
$exc =~ s/^.*:://;
no strict qw(subs refs);
*{"${caller}\:\:${exc}\:\:"} = \*{__PACKAGE__ . "\:\:${exc}\:\:"};
}
但这最终要求我使用Klass::Foo::Bar::NameError 而不仅仅是NameError 调用异常。看起来效果不错,但效果也不错。
我不想将NameError 导入main::!
恐怕Typeglobs和符号表对我来说还是有点神秘。
我确信有一种方法可以做我想做的事(或者我正在做一些我完全不应该做的事情,但我们暂时不要管它)。谁能帮我解决这个问题?
谢谢!
【问题讨论】:
标签: perl exception-handling namespaces packages perl-module