Perl 5 provides a special package which is the ancestor of all other packages in a very object-oriented way. The UNIVERSAL
package provides a few methods available for all other classes and objects.
The isa()
method takes a string containing the name of a class or the name of a built-in type. You can call it as a class method or an instance method on an object. It returns true if the class or object is or derives from the named class, or if the object itself 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:
Built-in types are SCALAR
, ARRAY
, HASH
, REGEX
, IO
, and CODE
.
You can override isa()
in your own classes. This can be useful when working with mock objects (see Test::MockObject
and Test::MockModule
on the CPAN, for example) or with code that does not use roles (roles).
The can()
method takes the string containing the name of a method (though see method_sub_equivalence for a disclaimer). It returns a reference to the function which implements that method, if it exists. Otherwise, it returns false. 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.
Given a class named SpiderMonkey
with a method named screech
, you can get a reference to the method with:
Given a plugin-style architecture, you can test to see if a package implements a specific function in a similar way:
You can (and should) override can()
in your own code if you use AUTOLOAD()
. See autoload_drawbacks for a longer explanation.
The VERSION()
method is available to all packages, classes, and objects. It returns the value of the $VERSION
variable for the appropriate package or class. It takes a version number as an optional parameter. If you provide 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
:
You can override VERSION()
in your own code, but there's little reason to do so.
The DOES()
method is 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 performs that role. (The class may do so through inheritance, through delegation, through composition, through 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 perform a role. Given a Cappuchin
:
You can (and should) override DOES()
in your own code if you manually provide a role or other allomorphic behavior. Alternately, use Moose
and don't worry about the details.
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 find and eliminate old idioms which prevent good uses of polymorphism (though see Perl::Critic
for a different approach with other advantages).
The UNIVERSAL::require
module adds useful behavior to help load modules and classes at runtime--though using a distribution such as Module::Pluggable
is safer and less invasive.
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<>