Skip to content

Latest commit

 

History

History
177 lines (124 loc) · 5.89 KB

universal.pod

File metadata and controls

177 lines (124 loc) · 5.89 KB

The UNIVERSAL Package

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

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

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

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

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.

Extending UNIVERSAL

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.

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 3:

A non-empty Z<>