在Perl中获取对象的类名

时间:2011-09-26 13:44:27

标签: perl

我有一个对象引用,它可能是对'FooInvalidResults'类型对象的引用

有一个名为FooInvalidResults.pm的文件,其中有一行“包FooInvalidResults”。

将进行以下工作吗?

my $class = blessed $result;
if ($class eq 'FooInvalidResults') {
  # do something
} else {
  # do something else
}

3 个答案:

答案 0 :(得分:15)

字符串比较类名称通常是一个坏主意,因为它打破了基于子类型的多态性,并且因为对于对象的私密细节(如其确切的包名称)而言,通常不是很好的OO实践。

相反,请写$result->isa('FooInvalidResults') - 或者,如果您对$result根本不是对象的可能性感到偏执,blessed $result && $result->isa('FooInvalidResults')

使用UNIVERSAL::isa是一个坏主意,因为某些对象(例如,用于测试的模拟对象)有合理的理由来覆盖isa方法,并且调用UNIVERSAL::isa会破坏它。

答案 1 :(得分:1)

为什么不使用UNIVERSAL::isa

if UNIVERSAL::isa( $result, "FooInvalidResults" ) {
   ...
}

这是错误的建议,请使用

$obj->isa( 'FooInvalidResults' );

我没有完全意识到子程序调用(BAD)和方法调用(GOOD)之间的区别,但在我自己做了一些RTFM(perldoc UNIVERSAL)之后就变得清晰了。 谢谢(和+1)所有指出我的错误的人。

答案 2 :(得分:0)

也可以使用ref()内置而非Scalar::Util::blessed()来完成工作:

$ perl -E '$ref = {}; bless $ref => "Foo"; say ref $ref'
Foo

请注意,如果引用未被祝福,则返回引用类型:

$ perl -E '$ref = {}; say ref $ref'
HASH

但是,正如其他人所提到的,UNIVERSAL::isa是更好的解决方案。