For Data::Domain I needed a way to test if something is a Perl class. Since UNIVERSAL is the mother of all classes, it seemed to make sense to define the test as
defined($_) && !ref($_) && $_->isa('UNIVERSAL')
Other people did it through $_->can('can') or UNIVERSAL::can($_, 'can'). Both ways used to work fine, but this is no longer true since June 22, 2012 (bleadperl commit 68b4061) : now just any string matches these conditions.
At first I found this change a bit odd, but somehow it makes sense because any string will answer to the 'can' and 'isa' methods. Also, bless({}, 'Foo') and 'Foo' now return consistent answers for ->isa() and for ->can(), which was not the case before. So let's agree that this change was a good step.
But now it means that while every object or class is a UNIVERSAL, the reverse is not true : things that are UNIVERSAL are not necessarily objects or classes. Hum ... but what "is a class", really ?
Moose type 'ClassName' defines this through Class::Load::is_class_loaded, which returns true if this is a package with a $VERSION, with an @ISA, or with at least one method. By this definition, an empty package is not a class. However, perldoc says that a class is "just a package", with no restriction.
So after some thoughts I ended up with this implementation :
defined($_) && !ref($_) && $_->can($_)
This returns true for any defined package, false otherwise, and works both before and after June 22.
Thoughts ?
Subscribe to:
Post Comments (Atom)
defined @{$_.'::'}
ReplyDeleteHello openid person... the problem with this is that it evaluates to true for package "Foo" if only package "Foo::Bar" is defined.
ReplyDeleteUse Scalar::Util::blessed
ReplyDelete> Use Scalar::Util::blessed
DeleteWell, no, this tells if something is an _object_, but not if a given string is a _class_
Great post thank yoou
ReplyDeletekuşadası
ReplyDeletemilas
çeşme
bağcılar
tekirdağ
AWMXU