Perl 5's builtin UNIVERSAL
package is the ancestor of all other packages--in the object-oriented sense (moose). UNIVERSAL
provides a few methods for its children to inherit or override.
The isa()
method takes a string containing the name of a class or the name of a builtin type. Call it as a class method or an instance method on an object. It returns a true value if its invocant is or derives from the named class, or if the invocant is a blessed reference to the given type.
Given an object $pepper
(a hash reference blessed into the Monkey
class, which inherits from the Mammal
class):
Perl 5's core types are SCALAR
, ARRAY
, HASH
, Regexp
, IO
, and CODE
.
Any class may override isa()
. This can be useful when working with mock objects (see Test::MockObject
and Test::MockModule
on the CPAN) or with code that does not use roles (roles). Be aware that any class which does override isa()
generally has a good reason for doing so.
The can()
method takes a string containing the name of a method. It returns a reference to the function which implements that method, if it exists. Otherwise, it returns a false value. You may call this on a class, an object, or the name of a package. In the latter case, it returns a reference to a function, not a method... not that you can tell the difference, given only a reference..
Given a class named SpiderMonkey
with a method named screech
, get a reference to the method with:
Use can()
to test if a package implements a specific function or method:
The VERSION()
method returns the value of the $VERSION
variable for the appropriate package or class. If you provide a version number as an optional parameter, this version number, the method will throw an exception if the queried $VERSION
is not equal to or greater than the parameter.
Given a HowlerMonkey
module of version 1.23
:
There's little reason to override VERSION()
.
The DOES()
method was new in Perl 5.10.0. It exists to support the use of roles (roles) in programs. Pass it an invocant and the name of a role, and the method will return true if the appropriate class somehow does that role--whether through inheritance, delegation, composition, role application, or any other mechanism.
The default implementation of DOES()
falls back to isa()
, because inheritance is one mechanism by which a class may do a role. Given a Cappuchin
:
Override DOES()
if you manually provide a role or provide other allomorphic behavior.
It's tempting to store other methods in UNIVERSAL
to make it available to all other classes and objects in Perl 5. Avoid this temptation; this global behavior can have subtle side effects because it is unconstrained.
With that said, occasional abuse of UNIVERSAL
for debugging purposes and to fix improper default behavior may be excusable. For example, Joshua ben Jore's UNIVERSAL::ref
distribution makes the nearly-useless ref()
operator usable. The UNIVERSAL::can
and UNIVERSAL::isa
distributions can help you debug anti-polymorphism bugs (method_sub_equivalence). Perl::Critic
can detect those and other problems.
Outside of very carefully controlled code and very specific, very pragmatic situations, there's no reason to put code in UNIVERSAL
directly. There are almost always much better design alternatives.
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 60:
-
Deleting unknown formatting code N<>