summaryrefslogtreecommitdiffstats
path: root/upstream/debian-bookworm/man1/perlobj.1
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/debian-bookworm/man1/perlobj.1')
-rw-r--r--upstream/debian-bookworm/man1/perlobj.11219
1 files changed, 1219 insertions, 0 deletions
diff --git a/upstream/debian-bookworm/man1/perlobj.1 b/upstream/debian-bookworm/man1/perlobj.1
new file mode 100644
index 00000000..6bea4cef
--- /dev/null
+++ b/upstream/debian-bookworm/man1/perlobj.1
@@ -0,0 +1,1219 @@
+.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLOBJ 1"
+.TH PERLOBJ 1 "2023-11-25" "perl v5.36.0" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+perlobj \- Perl object reference
+.IX Xref "object OOP"
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This document provides a reference for Perl's object orientation
+features. If you're looking for an introduction to object-oriented
+programming in Perl, please see perlootut.
+.PP
+In order to understand Perl objects, you first need to understand
+references in Perl. See perlreftut for details.
+.PP
+This document describes all of Perl's object-oriented (\s-1OO\s0) features
+from the ground up. If you're just looking to write some
+object-oriented code of your own, you are probably better served by
+using one of the object systems from \s-1CPAN\s0 described in perlootut.
+.PP
+If you're looking to write your own object system, or you need to
+maintain code which implements objects from scratch then this document
+will help you understand exactly how Perl does object orientation.
+.PP
+There are a few basic principles which define object oriented Perl:
+.IP "1." 4
+An object is simply a data structure that knows to which class it
+belongs.
+.IP "2." 4
+A class is simply a package. A class provides methods that expect to
+operate on objects.
+.IP "3." 4
+A method is simply a subroutine that expects a reference to an object
+(or a package name, for class methods) as the first argument.
+.PP
+Let's look at each of these principles in depth.
+.SS "An Object is Simply a Data Structure"
+.IX Xref "object bless constructor new"
+.IX Subsection "An Object is Simply a Data Structure"
+Unlike many other languages which support object orientation, Perl does
+not provide any special syntax for constructing an object. Objects are
+merely Perl data structures (hashes, arrays, scalars, filehandles,
+etc.) that have been explicitly associated with a particular class.
+.PP
+That explicit association is created by the built-in \f(CW\*(C`bless\*(C'\fR function,
+which is typically used within the \fIconstructor\fR subroutine of the
+class.
+.PP
+Here is a simple constructor:
+.PP
+.Vb 1
+\& package File;
+\&
+\& sub new {
+\& my $class = shift;
+\&
+\& return bless {}, $class;
+\& }
+.Ve
+.PP
+The name \f(CW\*(C`new\*(C'\fR isn't special. We could name our constructor something
+else:
+.PP
+.Vb 1
+\& package File;
+\&
+\& sub load {
+\& my $class = shift;
+\&
+\& return bless {}, $class;
+\& }
+.Ve
+.PP
+The modern convention for \s-1OO\s0 modules is to always use \f(CW\*(C`new\*(C'\fR as the
+name for the constructor, but there is no requirement to do so. Any
+subroutine that blesses a data structure into a class is a valid
+constructor in Perl.
+.PP
+In the previous examples, the \f(CW\*(C`{}\*(C'\fR code creates a reference to an
+empty anonymous hash. The \f(CW\*(C`bless\*(C'\fR function then takes that reference
+and associates the hash with the class in \f(CW$class\fR. In the simplest
+case, the \f(CW$class\fR variable will end up containing the string \*(L"File\*(R".
+.PP
+We can also use a variable to store a reference to the data structure
+that is being blessed as our object:
+.PP
+.Vb 2
+\& sub new {
+\& my $class = shift;
+\&
+\& my $self = {};
+\& bless $self, $class;
+\&
+\& return $self;
+\& }
+.Ve
+.PP
+Once we've blessed the hash referred to by \f(CW$self\fR we can start
+calling methods on it. This is useful if you want to put object
+initialization in its own separate method:
+.PP
+.Vb 2
+\& sub new {
+\& my $class = shift;
+\&
+\& my $self = {};
+\& bless $self, $class;
+\&
+\& $self\->_initialize();
+\&
+\& return $self;
+\& }
+.Ve
+.PP
+Since the object is also a hash, you can treat it as one, using it to
+store data associated with the object. Typically, code inside the class
+can treat the hash as an accessible data structure, while code outside
+the class should always treat the object as opaque. This is called
+\&\fBencapsulation\fR. Encapsulation means that the user of an object does
+not have to know how it is implemented. The user simply calls
+documented methods on the object.
+.PP
+Note, however, that (unlike most other \s-1OO\s0 languages) Perl does not
+ensure or enforce encapsulation in any way. If you want objects to
+actually \fIbe\fR opaque you need to arrange for that yourself. This can
+be done in a variety of ways, including using \*(L"Inside-Out objects\*(R"
+or modules from \s-1CPAN.\s0
+.PP
+\fIObjects Are Blessed; Variables Are Not\fR
+.IX Subsection "Objects Are Blessed; Variables Are Not"
+.PP
+When we bless something, we are not blessing the variable which
+contains a reference to that thing, nor are we blessing the reference
+that the variable stores; we are blessing the thing that the variable
+refers to (sometimes known as the \fIreferent\fR). This is best
+demonstrated with this code:
+.PP
+.Vb 1
+\& use Scalar::Util \*(Aqblessed\*(Aq;
+\&
+\& my $foo = {};
+\& my $bar = $foo;
+\&
+\& bless $foo, \*(AqClass\*(Aq;
+\& print blessed( $bar ) // \*(Aqnot blessed\*(Aq; # prints "Class"
+\&
+\& $bar = "some other value";
+\& print blessed( $bar ) // \*(Aqnot blessed\*(Aq; # prints "not blessed"
+.Ve
+.PP
+When we call \f(CW\*(C`bless\*(C'\fR on a variable, we are actually blessing the
+underlying data structure that the variable refers to. We are not
+blessing the reference itself, nor the variable that contains that
+reference. That's why the second call to \f(CW\*(C`blessed( $bar )\*(C'\fR returns
+false. At that point \f(CW$bar\fR is no longer storing a reference to an
+object.
+.PP
+You will sometimes see older books or documentation mention \*(L"blessing a
+reference\*(R" or describe an object as a \*(L"blessed reference\*(R", but this is
+incorrect. It isn't the reference that is blessed as an object; it's
+the thing the reference refers to (i.e. the referent).
+.SS "A Class is Simply a Package"
+.IX Xref "class package @ISA inheritance"
+.IX Subsection "A Class is Simply a Package"
+Perl does not provide any special syntax for class definitions. A
+package is simply a namespace containing variables and subroutines. The
+only difference is that in a class, the subroutines may expect a
+reference to an object or the name of a class as the first argument.
+This is purely a matter of convention, so a class may contain both
+methods and subroutines which \fIdon't\fR operate on an object or class.
+.PP
+Each package contains a special array called \f(CW@ISA\fR. The \f(CW@ISA\fR array
+contains a list of that class's parent classes, if any. This array is
+examined when Perl does method resolution, which we will cover later.
+.PP
+Calling methods from a package means it must be loaded, of course, so
+you will often want to load a module and add it to \f(CW@ISA\fR at the same
+time. You can do so in a single step using the parent pragma.
+(In older code you may encounter the base pragma, which is nowadays
+discouraged except when you have to work with the equally discouraged
+fields pragma.)
+.PP
+However the parent classes are set, the package's \f(CW@ISA\fR variable will
+contain a list of those parents. This is simply a list of scalars, each
+of which is a string that corresponds to a package name.
+.PP
+All classes inherit from the \s-1UNIVERSAL\s0 class implicitly. The
+\&\s-1UNIVERSAL\s0 class is implemented by the Perl core, and provides
+several default methods, such as \f(CW\*(C`isa()\*(C'\fR, \f(CW\*(C`can()\*(C'\fR, and \f(CW\*(C`VERSION()\*(C'\fR.
+The \f(CW\*(C`UNIVERSAL\*(C'\fR class will \fInever\fR appear in a package's \f(CW@ISA\fR
+variable.
+.PP
+Perl \fIonly\fR provides method inheritance as a built-in feature.
+Attribute inheritance is left up the class to implement. See the
+\&\*(L"Writing Accessors\*(R" section for details.
+.SS "A Method is Simply a Subroutine"
+.IX Xref "method"
+.IX Subsection "A Method is Simply a Subroutine"
+Perl does not provide any special syntax for defining a method. A
+method is simply a regular subroutine, and is declared with \f(CW\*(C`sub\*(C'\fR.
+What makes a method special is that it expects to receive either an
+object or a class name as its first argument.
+.PP
+Perl \fIdoes\fR provide special syntax for method invocation, the \f(CW\*(C`\->\*(C'\fR operator. We will cover this in more detail later.
+.PP
+Most methods you write will expect to operate on objects:
+.PP
+.Vb 2
+\& sub save {
+\& my $self = shift;
+\&
+\& open my $fh, \*(Aq>\*(Aq, $self\->path() or die $!;
+\& print {$fh} $self\->data() or die $!;
+\& close $fh or die $!;
+\& }
+.Ve
+.SS "Method Invocation"
+.IX Xref "invocation method arrow ->"
+.IX Subsection "Method Invocation"
+Calling a method on an object is written as \f(CW\*(C`$object\->method\*(C'\fR.
+.PP
+The left hand side of the method invocation (or arrow) operator is the
+object (or class name), and the right hand side is the method name.
+.PP
+.Vb 2
+\& my $pod = File\->new( \*(Aqperlobj.pod\*(Aq, $data );
+\& $pod\->save();
+.Ve
+.PP
+The \f(CW\*(C`\->\*(C'\fR syntax is also used when dereferencing a reference. It
+looks like the same operator, but these are two different operations.
+.PP
+When you call a method, the thing on the left side of the arrow is
+passed as the first argument to the method. That means when we call \f(CW\*(C`Critter\->new()\*(C'\fR, the \f(CW\*(C`new()\*(C'\fR method receives the string \f(CW"Critter"\fR
+as its first argument. When we call \f(CW\*(C`$fred\->speak()\*(C'\fR, the \f(CW$fred\fR
+variable is passed as the first argument to \f(CW\*(C`speak()\*(C'\fR.
+.PP
+Just as with any Perl subroutine, all of the arguments passed in \f(CW@_\fR
+are aliases to the original argument. This includes the object itself.
+If you assign directly to \f(CW$_[0]\fR you will change the contents of the
+variable that holds the reference to the object. We recommend that you
+don't do this unless you know exactly what you're doing.
+.PP
+Perl knows what package the method is in by looking at the left side of
+the arrow. If the left hand side is a package name, it looks for the
+method in that package. If the left hand side is an object, then Perl
+looks for the method in the package that the object has been blessed
+into.
+.PP
+If the left hand side is neither a package name nor an object, then the
+method call will cause an error, but see the section on \*(L"Method Call
+Variations\*(R" for more nuances.
+.SS "Inheritance"
+.IX Xref "inheritance"
+.IX Subsection "Inheritance"
+We already talked about the special \f(CW@ISA\fR array and the parent
+pragma.
+.PP
+When a class inherits from another class, any methods defined in the
+parent class are available to the child class. If you attempt to call a
+method on an object that isn't defined in its own class, Perl will also
+look for that method in any parent classes it may have.
+.PP
+.Vb 2
+\& package File::MP3;
+\& use parent \*(AqFile\*(Aq; # sets @File::MP3::ISA = (\*(AqFile\*(Aq);
+\&
+\& my $mp3 = File::MP3\->new( \*(AqAndvari.mp3\*(Aq, $data );
+\& $mp3\->save();
+.Ve
+.PP
+Since we didn't define a \f(CW\*(C`save()\*(C'\fR method in the \f(CW\*(C`File::MP3\*(C'\fR class,
+Perl will look at the \f(CW\*(C`File::MP3\*(C'\fR class's parent classes to find the
+\&\f(CW\*(C`save()\*(C'\fR method. If Perl cannot find a \f(CW\*(C`save()\*(C'\fR method anywhere in
+the inheritance hierarchy, it will die.
+.PP
+In this case, it finds a \f(CW\*(C`save()\*(C'\fR method in the \f(CW\*(C`File\*(C'\fR class. Note
+that the object passed to \f(CW\*(C`save()\*(C'\fR in this case is still a
+\&\f(CW\*(C`File::MP3\*(C'\fR object, even though the method is found in the \f(CW\*(C`File\*(C'\fR
+class.
+.PP
+We can override a parent's method in a child class. When we do so, we
+can still call the parent class's method with the \f(CW\*(C`SUPER\*(C'\fR
+pseudo-class.
+.PP
+.Vb 2
+\& sub save {
+\& my $self = shift;
+\&
+\& say \*(AqPrepare to rock\*(Aq;
+\& $self\->SUPER::save();
+\& }
+.Ve
+.PP
+The \f(CW\*(C`SUPER\*(C'\fR modifier can \fIonly\fR be used for method calls. You can't
+use it for regular subroutine calls or class methods:
+.PP
+.Vb 1
+\& SUPER::save($thing); # FAIL: looks for save() sub in package SUPER
+\&
+\& SUPER\->save($thing); # FAIL: looks for save() method in class
+\& # SUPER
+\&
+\& $thing\->SUPER::save(); # Okay: looks for save() method in parent
+\& # classes
+.Ve
+.PP
+\fIHow \s-1SUPER\s0 is Resolved\fR
+.IX Xref "SUPER"
+.IX Subsection "How SUPER is Resolved"
+.PP
+The \f(CW\*(C`SUPER\*(C'\fR pseudo-class is resolved from the package where the call
+is made. It is \fInot\fR resolved based on the object's class. This is
+important, because it lets methods at different levels within a deep
+inheritance hierarchy each correctly call their respective parent
+methods.
+.PP
+.Vb 1
+\& package A;
+\&
+\& sub new {
+\& return bless {}, shift;
+\& }
+\&
+\& sub speak {
+\& my $self = shift;
+\&
+\& say \*(AqA\*(Aq;
+\& }
+\&
+\& package B;
+\&
+\& use parent \-norequire, \*(AqA\*(Aq;
+\&
+\& sub speak {
+\& my $self = shift;
+\&
+\& $self\->SUPER::speak();
+\&
+\& say \*(AqB\*(Aq;
+\& }
+\&
+\& package C;
+\&
+\& use parent \-norequire, \*(AqB\*(Aq;
+\&
+\& sub speak {
+\& my $self = shift;
+\&
+\& $self\->SUPER::speak();
+\&
+\& say \*(AqC\*(Aq;
+\& }
+\&
+\& my $c = C\->new();
+\& $c\->speak();
+.Ve
+.PP
+In this example, we will get the following output:
+.PP
+.Vb 3
+\& A
+\& B
+\& C
+.Ve
+.PP
+This demonstrates how \f(CW\*(C`SUPER\*(C'\fR is resolved. Even though the object is
+blessed into the \f(CW\*(C`C\*(C'\fR class, the \f(CW\*(C`speak()\*(C'\fR method in the \f(CW\*(C`B\*(C'\fR class
+can still call \f(CW\*(C`SUPER::speak()\*(C'\fR and expect it to correctly look in the
+parent class of \f(CW\*(C`B\*(C'\fR (i.e the class the method call is in), not in the
+parent class of \f(CW\*(C`C\*(C'\fR (i.e. the class the object belongs to).
+.PP
+There are rare cases where this package-based resolution can be a
+problem. If you copy a subroutine from one package to another, \f(CW\*(C`SUPER\*(C'\fR
+resolution will be done based on the original package.
+.PP
+\fIMultiple Inheritance\fR
+.IX Xref "multiple inheritance"
+.IX Subsection "Multiple Inheritance"
+.PP
+Multiple inheritance often indicates a design problem, but Perl always
+gives you enough rope to hang yourself with if you ask for it.
+.PP
+To declare multiple parents, you simply need to pass multiple class
+names to \f(CW\*(C`use parent\*(C'\fR:
+.PP
+.Vb 1
+\& package MultiChild;
+\&
+\& use parent \*(AqParent1\*(Aq, \*(AqParent2\*(Aq;
+.Ve
+.PP
+\fIMethod Resolution Order\fR
+.IX Xref "method resolution order mro"
+.IX Subsection "Method Resolution Order"
+.PP
+Method resolution order only matters in the case of multiple
+inheritance. In the case of single inheritance, Perl simply looks up
+the inheritance chain to find a method:
+.PP
+.Vb 5
+\& Grandparent
+\& |
+\& Parent
+\& |
+\& Child
+.Ve
+.PP
+If we call a method on a \f(CW\*(C`Child\*(C'\fR object and that method is not defined
+in the \f(CW\*(C`Child\*(C'\fR class, Perl will look for that method in the \f(CW\*(C`Parent\*(C'\fR
+class and then, if necessary, in the \f(CW\*(C`Grandparent\*(C'\fR class.
+.PP
+If Perl cannot find the method in any of these classes, it will die
+with an error message.
+.PP
+When a class has multiple parents, the method lookup order becomes more
+complicated.
+.PP
+By default, Perl does a depth-first left-to-right search for a method.
+That means it starts with the first parent in the \f(CW@ISA\fR array, and
+then searches all of its parents, grandparents, etc. If it fails to
+find the method, it then goes to the next parent in the original
+class's \f(CW@ISA\fR array and searches from there.
+.PP
+.Vb 7
+\& SharedGreatGrandParent
+\& / \e
+\& PaternalGrandparent MaternalGrandparent
+\& \e /
+\& Father Mother
+\& \e /
+\& Child
+.Ve
+.PP
+So given the diagram above, Perl will search \f(CW\*(C`Child\*(C'\fR, \f(CW\*(C`Father\*(C'\fR,
+\&\f(CW\*(C`PaternalGrandparent\*(C'\fR, \f(CW\*(C`SharedGreatGrandParent\*(C'\fR, \f(CW\*(C`Mother\*(C'\fR, and
+finally \f(CW\*(C`MaternalGrandparent\*(C'\fR. This may be a problem because now we're
+looking in \f(CW\*(C`SharedGreatGrandParent\*(C'\fR \fIbefore\fR we've checked all its
+derived classes (i.e. before we tried \f(CW\*(C`Mother\*(C'\fR and
+\&\f(CW\*(C`MaternalGrandparent\*(C'\fR).
+.PP
+It is possible to ask for a different method resolution order with the
+mro pragma.
+.PP
+.Vb 1
+\& package Child;
+\&
+\& use mro \*(Aqc3\*(Aq;
+\& use parent \*(AqFather\*(Aq, \*(AqMother\*(Aq;
+.Ve
+.PP
+This pragma lets you switch to the \*(L"C3\*(R" resolution order. In simple
+terms, \*(L"C3\*(R" order ensures that shared parent classes are never searched
+before child classes, so Perl will now search: \f(CW\*(C`Child\*(C'\fR, \f(CW\*(C`Father\*(C'\fR,
+\&\f(CW\*(C`PaternalGrandparent\*(C'\fR, \f(CW\*(C`Mother\*(C'\fR \f(CW\*(C`MaternalGrandparent\*(C'\fR, and finally
+\&\f(CW\*(C`SharedGreatGrandParent\*(C'\fR. Note however that this is not
+\&\*(L"breadth-first\*(R" searching: All the \f(CW\*(C`Father\*(C'\fR ancestors (except the
+common ancestor) are searched before any of the \f(CW\*(C`Mother\*(C'\fR ancestors are
+considered.
+.PP
+The C3 order also lets you call methods in sibling classes with the
+\&\f(CW\*(C`next\*(C'\fR pseudo-class. See the mro documentation for more details on
+this feature.
+.PP
+\fIMethod Resolution Caching\fR
+.IX Subsection "Method Resolution Caching"
+.PP
+When Perl searches for a method, it caches the lookup so that future
+calls to the method do not need to search for it again. Changing a
+class's parent class or adding subroutines to a class will invalidate
+the cache for that class.
+.PP
+The mro pragma provides some functions for manipulating the method
+cache directly.
+.SS "Writing Constructors"
+.IX Xref "constructor"
+.IX Subsection "Writing Constructors"
+As we mentioned earlier, Perl provides no special constructor syntax.
+This means that a class must implement its own constructor. A
+constructor is simply a class method that returns a reference to a new
+object.
+.PP
+The constructor can also accept additional parameters that define the
+object. Let's write a real constructor for the \f(CW\*(C`File\*(C'\fR class we used
+earlier:
+.PP
+.Vb 1
+\& package File;
+\&
+\& sub new {
+\& my $class = shift;
+\& my ( $path, $data ) = @_;
+\&
+\& my $self = bless {
+\& path => $path,
+\& data => $data,
+\& }, $class;
+\&
+\& return $self;
+\& }
+.Ve
+.PP
+As you can see, we've stored the path and file data in the object
+itself. Remember, under the hood, this object is still just a hash.
+Later, we'll write accessors to manipulate this data.
+.PP
+For our \f(CW\*(C`File::MP3\*(C'\fR class, we can check to make sure that the path
+we're given ends with \*(L".mp3\*(R":
+.PP
+.Vb 1
+\& package File::MP3;
+\&
+\& sub new {
+\& my $class = shift;
+\& my ( $path, $data ) = @_;
+\&
+\& die "You cannot create a File::MP3 without an mp3 extension\en"
+\& unless $path =~ /\e.mp3\ez/;
+\&
+\& return $class\->SUPER::new(@_);
+\& }
+.Ve
+.PP
+This constructor lets its parent class do the actual object
+construction.
+.SS "Attributes"
+.IX Xref "attribute"
+.IX Subsection "Attributes"
+An attribute is a piece of data belonging to a particular object.
+Unlike most object-oriented languages, Perl provides no special syntax
+or support for declaring and manipulating attributes.
+.PP
+Attributes are often stored in the object itself. For example, if the
+object is an anonymous hash, we can store the attribute values in the
+hash using the attribute name as the key.
+.PP
+While it's possible to refer directly to these hash keys outside of the
+class, it's considered a best practice to wrap all access to the
+attribute with accessor methods.
+.PP
+This has several advantages. Accessors make it easier to change the
+implementation of an object later while still preserving the original
+\&\s-1API.\s0
+.PP
+An accessor lets you add additional code around attribute access. For
+example, you could apply a default to an attribute that wasn't set in
+the constructor, or you could validate that a new value for the
+attribute is acceptable.
+.PP
+Finally, using accessors makes inheritance much simpler. Subclasses can
+use the accessors rather than having to know how a parent class is
+implemented internally.
+.PP
+\fIWriting Accessors\fR
+.IX Xref "accessor"
+.IX Subsection "Writing Accessors"
+.PP
+As with constructors, Perl provides no special accessor declaration
+syntax, so classes must provide explicitly written accessor methods.
+There are two common types of accessors, read-only and read-write.
+.PP
+A simple read-only accessor simply gets the value of a single
+attribute:
+.PP
+.Vb 2
+\& sub path {
+\& my $self = shift;
+\&
+\& return $self\->{path};
+\& }
+.Ve
+.PP
+A read-write accessor will allow the caller to set the value as well as
+get it:
+.PP
+.Vb 2
+\& sub path {
+\& my $self = shift;
+\&
+\& if (@_) {
+\& $self\->{path} = shift;
+\& }
+\&
+\& return $self\->{path};
+\& }
+.Ve
+.SS "An Aside About Smarter and Safer Code"
+.IX Subsection "An Aside About Smarter and Safer Code"
+Our constructor and accessors are not very smart. They don't check that
+a \f(CW$path\fR is defined, nor do they check that a \f(CW$path\fR is a valid
+filesystem path.
+.PP
+Doing these checks by hand can quickly become tedious. Writing a bunch
+of accessors by hand is also incredibly tedious. There are a lot of
+modules on \s-1CPAN\s0 that can help you write safer and more concise code,
+including the modules we recommend in perlootut.
+.SS "Method Call Variations"
+.IX Xref "method"
+.IX Subsection "Method Call Variations"
+Perl supports several other ways to call methods besides the \f(CW\*(C`$object\->method()\*(C'\fR usage we've seen so far.
+.PP
+\fIMethod Names with a Fully Qualified Name\fR
+.IX Subsection "Method Names with a Fully Qualified Name"
+.PP
+Perl allows you to call methods using their fully qualified name (the
+package and method name):
+.PP
+.Vb 2
+\& my $mp3 = File::MP3\->new( \*(AqRegin.mp3\*(Aq, $data );
+\& $mp3\->File::save();
+.Ve
+.PP
+When you call a fully qualified method name like \f(CW\*(C`File::save\*(C'\fR, the method
+resolution search for the \f(CW\*(C`save\*(C'\fR method starts in the \f(CW\*(C`File\*(C'\fR class,
+skipping any \f(CW\*(C`save\*(C'\fR method the \f(CW\*(C`File::MP3\*(C'\fR class may have defined. It
+still searches the \f(CW\*(C`File\*(C'\fR class's parents if necessary.
+.PP
+While this feature is most commonly used to explicitly call methods
+inherited from an ancestor class, there is no technical restriction
+that enforces this:
+.PP
+.Vb 2
+\& my $obj = Tree\->new();
+\& $obj\->Dog::bark();
+.Ve
+.PP
+This calls the \f(CW\*(C`bark\*(C'\fR method from class \f(CW\*(C`Dog\*(C'\fR on an object of class
+\&\f(CW\*(C`Tree\*(C'\fR, even if the two classes are completely unrelated. Use this
+with great care.
+.PP
+The \f(CW\*(C`SUPER\*(C'\fR pseudo-class that was described earlier is \fInot\fR the same
+as calling a method with a fully-qualified name. See the earlier
+\&\*(L"Inheritance\*(R" section for details.
+.PP
+\fIMethod Names as Strings\fR
+.IX Subsection "Method Names as Strings"
+.PP
+Perl lets you use a scalar variable containing a string as a method
+name:
+.PP
+.Vb 1
+\& my $file = File\->new( $path, $data );
+\&
+\& my $method = \*(Aqsave\*(Aq;
+\& $file\->$method();
+.Ve
+.PP
+This works exactly like calling \f(CW\*(C`$file\->save()\*(C'\fR. This can be very
+useful for writing dynamic code. For example, it allows you to pass a
+method name to be called as a parameter to another method.
+.PP
+\fIClass Names as Strings\fR
+.IX Subsection "Class Names as Strings"
+.PP
+Perl also lets you use a scalar containing a string as a class name:
+.PP
+.Vb 1
+\& my $class = \*(AqFile\*(Aq;
+\&
+\& my $file = $class\->new( $path, $data );
+.Ve
+.PP
+Again, this allows for very dynamic code.
+.PP
+\fISubroutine References as Methods\fR
+.IX Subsection "Subroutine References as Methods"
+.PP
+You can also use a subroutine reference as a method:
+.PP
+.Vb 2
+\& my $sub = sub {
+\& my $self = shift;
+\&
+\& $self\->save();
+\& };
+\&
+\& $file\->$sub();
+.Ve
+.PP
+This is exactly equivalent to writing \f(CW\*(C`$sub\->($file)\*(C'\fR. You may see
+this idiom in the wild combined with a call to \f(CW\*(C`can\*(C'\fR:
+.PP
+.Vb 3
+\& if ( my $meth = $object\->can(\*(Aqfoo\*(Aq) ) {
+\& $object\->$meth();
+\& }
+.Ve
+.PP
+\fIDereferencing Method Call\fR
+.IX Subsection "Dereferencing Method Call"
+.PP
+Perl also lets you use a dereferenced scalar reference in a method
+call. That's a mouthful, so let's look at some code:
+.PP
+.Vb 4
+\& $file\->${ \e\*(Aqsave\*(Aq };
+\& $file\->${ returns_scalar_ref() };
+\& $file\->${ \e( returns_scalar() ) };
+\& $file\->${ returns_ref_to_sub_ref() };
+.Ve
+.PP
+This works if the dereference produces a string \fIor\fR a subroutine
+reference.
+.PP
+\fIMethod Calls on Filehandles\fR
+.IX Subsection "Method Calls on Filehandles"
+.PP
+Under the hood, Perl filehandles are instances of the \f(CW\*(C`IO::Handle\*(C'\fR or
+\&\f(CW\*(C`IO::File\*(C'\fR class. Once you have an open filehandle, you can call
+methods on it. Additionally, you can call methods on the \f(CW\*(C`STDIN\*(C'\fR,
+\&\f(CW\*(C`STDOUT\*(C'\fR, and \f(CW\*(C`STDERR\*(C'\fR filehandles.
+.PP
+.Vb 3
+\& open my $fh, \*(Aq>\*(Aq, \*(Aqpath/to/file\*(Aq;
+\& $fh\->autoflush();
+\& $fh\->print(\*(Aqcontent\*(Aq);
+\&
+\& STDOUT\->autoflush();
+.Ve
+.SS "Invoking Class Methods"
+.IX Xref "invocation"
+.IX Subsection "Invoking Class Methods"
+Because Perl allows you to use barewords for package names and
+subroutine names, it sometimes interprets a bareword's meaning
+incorrectly. For example, the construct \f(CW\*(C`Class\->new()\*(C'\fR can be
+interpreted as either \f(CW\*(C`\*(AqClass\*(Aq\->new()\*(C'\fR or \f(CW\*(C`Class()\->new()\*(C'\fR.
+In English, that second interpretation reads as \*(L"call a subroutine
+named \fBClass()\fR, then call \fBnew()\fR as a method on the return value of
+\&\fBClass()\fR\*(R". If there is a subroutine named \f(CW\*(C`Class()\*(C'\fR in the current
+namespace, Perl will always interpret \f(CW\*(C`Class\->new()\*(C'\fR as the second
+alternative: a call to \f(CW\*(C`new()\*(C'\fR on the object returned by a call to
+\&\f(CW\*(C`Class()\*(C'\fR
+.PP
+You can force Perl to use the first interpretation (i.e. as a method
+call on the class named \*(L"Class\*(R") in two ways. First, you can append a
+\&\f(CW\*(C`::\*(C'\fR to the class name:
+.PP
+.Vb 1
+\& Class::\->new()
+.Ve
+.PP
+Perl will always interpret this as a method call.
+.PP
+Alternatively, you can quote the class name:
+.PP
+.Vb 1
+\& \*(AqClass\*(Aq\->new()
+.Ve
+.PP
+Of course, if the class name is in a scalar Perl will do the right
+thing as well:
+.PP
+.Vb 2
+\& my $class = \*(AqClass\*(Aq;
+\& $class\->new();
+.Ve
+.PP
+\fIIndirect Object Syntax\fR
+.IX Xref "indirect object"
+.IX Subsection "Indirect Object Syntax"
+.PP
+\&\fBOutside of the file handle case, use of this syntax is discouraged as
+it can confuse the Perl interpreter. See below for more details.\fR
+.PP
+Perl supports another method invocation syntax called \*(L"indirect object\*(R"
+notation. This syntax is called \*(L"indirect\*(R" because the method comes
+before the object it is being invoked on.
+.PP
+This syntax can be used with any class or object method:
+.PP
+.Vb 2
+\& my $file = new File $path, $data;
+\& save $file;
+.Ve
+.PP
+We recommend that you avoid this syntax, for several reasons.
+.PP
+First, it can be confusing to read. In the above example, it's not
+clear if \f(CW\*(C`save\*(C'\fR is a method provided by the \f(CW\*(C`File\*(C'\fR class or simply a
+subroutine that expects a file object as its first argument.
+.PP
+When used with class methods, the problem is even worse. Because Perl
+allows subroutine names to be written as barewords, Perl has to guess
+whether the bareword after the method is a class name or subroutine
+name. In other words, Perl can resolve the syntax as either \f(CW\*(C`File\->new( $path, $data )\*(C'\fR \fBor\fR \f(CW\*(C`new( File( $path, $data ) )\*(C'\fR.
+.PP
+To parse this code, Perl uses a heuristic based on what package names
+it has seen, what subroutines exist in the current package, what
+barewords it has previously seen, and other input. Needless to say,
+heuristics can produce very surprising results!
+.PP
+Older documentation (and some \s-1CPAN\s0 modules) encouraged this syntax,
+particularly for constructors, so you may still find it in the wild.
+However, we encourage you to avoid using it in new code.
+.PP
+You can force Perl to interpret the bareword as a class name by
+appending \*(L"::\*(R" to it, like we saw earlier:
+.PP
+.Vb 1
+\& my $file = new File:: $path, $data;
+.Ve
+.PP
+Indirect object syntax is only available when the
+\&\f(CW"indirect"\fR named feature is enabled.
+This is enabled by default, but can be disabled if requested. This
+feature is present in older feature version bundles, but was removed
+from the \f(CW\*(C`:5.36\*(C'\fR bundle; so a \f(CW\*(C`use VERSION\*(C'\fR
+declaration of \f(CW\*(C`v5.36\*(C'\fR or above will also disable the feature.
+.PP
+.Vb 2
+\& use v5.36;
+\& # indirect object syntax is no longer available
+.Ve
+.ie n .SS """bless"", ""blessed"", and ""ref"""
+.el .SS "\f(CWbless\fP, \f(CWblessed\fP, and \f(CWref\fP"
+.IX Subsection "bless, blessed, and ref"
+As we saw earlier, an object is simply a data structure that has been
+blessed into a class via the \f(CW\*(C`bless\*(C'\fR function. The \f(CW\*(C`bless\*(C'\fR function
+can take either one or two arguments:
+.PP
+.Vb 2
+\& my $object = bless {}, $class;
+\& my $object = bless {};
+.Ve
+.PP
+In the first form, the anonymous hash is being blessed into the class
+in \f(CW$class\fR. In the second form, the anonymous hash is blessed into
+the current package.
+.PP
+The second form is strongly discouraged, because it breaks the ability
+of a subclass to reuse the parent's constructor, but you may still run
+across it in existing code.
+.PP
+If you want to know whether a particular scalar refers to an object,
+you can use the \f(CW\*(C`blessed\*(C'\fR function exported by Scalar::Util, which
+is shipped with the Perl core.
+.PP
+.Vb 1
+\& use Scalar::Util \*(Aqblessed\*(Aq;
+\&
+\& if ( defined blessed($thing) ) { ... }
+.Ve
+.PP
+If \f(CW$thing\fR refers to an object, then this function returns the name
+of the package the object has been blessed into. If \f(CW$thing\fR doesn't
+contain a reference to a blessed object, the \f(CW\*(C`blessed\*(C'\fR function
+returns \f(CW\*(C`undef\*(C'\fR.
+.PP
+Note that \f(CW\*(C`blessed($thing)\*(C'\fR will also return false if \f(CW$thing\fR has
+been blessed into a class named \*(L"0\*(R". This is a possible, but quite
+pathological. Don't create a class named \*(L"0\*(R" unless you know what
+you're doing.
+.PP
+Similarly, Perl's built-in \f(CW\*(C`ref\*(C'\fR function treats a reference to a
+blessed object specially. If you call \f(CW\*(C`ref($thing)\*(C'\fR and \f(CW$thing\fR
+holds a reference to an object, it will return the name of the class
+that the object has been blessed into.
+.PP
+If you simply want to check that a variable contains an object
+reference, we recommend that you use \f(CW\*(C`defined blessed($object)\*(C'\fR, since
+\&\f(CW\*(C`ref\*(C'\fR returns true values for all references, not just objects.
+.SS "The \s-1UNIVERSAL\s0 Class"
+.IX Xref "UNIVERSAL"
+.IX Subsection "The UNIVERSAL Class"
+All classes automatically inherit from the \s-1UNIVERSAL\s0 class, which is
+built-in to the Perl core. This class provides a number of methods, all
+of which can be called on either a class or an object. You can also
+choose to override some of these methods in your class. If you do so,
+we recommend that you follow the built-in semantics described below.
+.IP "isa($class)" 4
+.IX Xref "isa"
+.IX Item "isa($class)"
+The \f(CW\*(C`isa\*(C'\fR method returns \fItrue\fR if the object is a member of the
+class in \f(CW$class\fR, or a member of a subclass of \f(CW$class\fR.
+.Sp
+If you override this method, it should never throw an exception.
+.IP "\s-1DOES\s0($role)" 4
+.IX Xref "DOES"
+.IX Item "DOES($role)"
+The \f(CW\*(C`DOES\*(C'\fR method returns \fItrue\fR if its object claims to perform the
+role \f(CW$role\fR. By default, this is equivalent to \f(CW\*(C`isa\*(C'\fR. This method is
+provided for use by object system extensions that implement roles, like
+\&\f(CW\*(C`Moose\*(C'\fR and \f(CW\*(C`Role::Tiny\*(C'\fR.
+.Sp
+You can also override \f(CW\*(C`DOES\*(C'\fR directly in your own classes. If you
+override this method, it should never throw an exception.
+.IP "can($method)" 4
+.IX Xref "can"
+.IX Item "can($method)"
+The \f(CW\*(C`can\*(C'\fR method checks to see if the class or object it was called on
+has a method named \f(CW$method\fR. This checks for the method in the class
+and all of its parents. If the method exists, then a reference to the
+subroutine is returned. If it does not then \f(CW\*(C`undef\*(C'\fR is returned.
+.Sp
+If your class responds to method calls via \f(CW\*(C`AUTOLOAD\*(C'\fR, you may want to
+overload \f(CW\*(C`can\*(C'\fR to return a subroutine reference for methods which your
+\&\f(CW\*(C`AUTOLOAD\*(C'\fR method handles.
+.Sp
+If you override this method, it should never throw an exception.
+.IP "\s-1VERSION\s0($need)" 4
+.IX Xref "VERSION"
+.IX Item "VERSION($need)"
+The \f(CW\*(C`VERSION\*(C'\fR method returns the version number of the class
+(package).
+.Sp
+If the \f(CW$need\fR argument is given then it will check that the current
+version (as defined by the \f(CW$VERSION\fR variable in the package) is greater
+than or equal to \f(CW$need\fR; it will die if this is not the case. This
+method is called automatically by the \f(CW\*(C`VERSION\*(C'\fR form of \f(CW\*(C`use\*(C'\fR.
+.Sp
+.Vb 3
+\& use Package 1.2 qw(some imported subs);
+\& # implies:
+\& Package\->VERSION(1.2);
+.Ve
+.Sp
+We recommend that you use this method to access another package's
+version, rather than looking directly at \f(CW$Package::VERSION\fR. The
+package you are looking at could have overridden the \f(CW\*(C`VERSION\*(C'\fR method.
+.Sp
+We also recommend using this method to check whether a module has a
+sufficient version. The internal implementation uses the version
+module to make sure that different types of version numbers are
+compared correctly.
+.SS "\s-1AUTOLOAD\s0"
+.IX Xref "AUTOLOAD"
+.IX Subsection "AUTOLOAD"
+If you call a method that doesn't exist in a class, Perl will throw an
+error. However, if that class or any of its parent classes defines an
+\&\f(CW\*(C`AUTOLOAD\*(C'\fR method, that \f(CW\*(C`AUTOLOAD\*(C'\fR method is called instead.
+.PP
+\&\f(CW\*(C`AUTOLOAD\*(C'\fR is called as a regular method, and the caller will not know
+the difference. Whatever value your \f(CW\*(C`AUTOLOAD\*(C'\fR method returns is
+returned to the caller.
+.PP
+The fully qualified method name that was called is available in the
+\&\f(CW$AUTOLOAD\fR package global for your class. Since this is a global, if
+you want to refer to do it without a package name prefix under \f(CW\*(C`strict
+\&\*(Aqvars\*(Aq\*(C'\fR, you need to declare it.
+.PP
+.Vb 5
+\& # XXX \- this is a terrible way to implement accessors, but it makes
+\& # for a simple example.
+\& our $AUTOLOAD;
+\& sub AUTOLOAD {
+\& my $self = shift;
+\&
+\& # Remove qualifier from original method name...
+\& my $called = $AUTOLOAD =~ s/.*:://r;
+\&
+\& # Is there an attribute of that name?
+\& die "No such attribute: $called"
+\& unless exists $self\->{$called};
+\&
+\& # If so, return it...
+\& return $self\->{$called};
+\& }
+\&
+\& sub DESTROY { } # see below
+.Ve
+.PP
+Without the \f(CW\*(C`our $AUTOLOAD\*(C'\fR declaration, this code will not compile
+under the strict pragma.
+.PP
+As the comment says, this is not a good way to implement accessors.
+It's slow and too clever by far. However, you may see this as a way to
+provide accessors in older Perl code. See perlootut for
+recommendations on \s-1OO\s0 coding in Perl.
+.PP
+If your class does have an \f(CW\*(C`AUTOLOAD\*(C'\fR method, we strongly recommend
+that you override \f(CW\*(C`can\*(C'\fR in your class as well. Your overridden \f(CW\*(C`can\*(C'\fR
+method should return a subroutine reference for any method that your
+\&\f(CW\*(C`AUTOLOAD\*(C'\fR responds to.
+.SS "Destructors"
+.IX Xref "destructor DESTROY"
+.IX Subsection "Destructors"
+When the last reference to an object goes away, the object is
+destroyed. If you only have one reference to an object stored in a
+lexical scalar, the object is destroyed when that scalar goes out of
+scope. If you store the object in a package global, that object may not
+go out of scope until the program exits.
+.PP
+If you want to do something when the object is destroyed, you can
+define a \f(CW\*(C`DESTROY\*(C'\fR method in your class. This method will always be
+called by Perl at the appropriate time, unless the method is empty.
+.PP
+This is called just like any other method, with the object as the first
+argument. It does not receive any additional arguments. However, the
+\&\f(CW$_[0]\fR variable will be read-only in the destructor, so you cannot
+assign a value to it.
+.PP
+If your \f(CW\*(C`DESTROY\*(C'\fR method throws an exception, this will not cause
+any control transfer beyond exiting the method. The exception will be
+reported to \f(CW\*(C`STDERR\*(C'\fR as a warning, marked \*(L"(in cleanup)\*(R", and Perl will
+continue with whatever it was doing before.
+.PP
+Because \f(CW\*(C`DESTROY\*(C'\fR methods can be called at any time, you should localize
+any global status variables that might be set by anything you do in
+your \f(CW\*(C`DESTROY\*(C'\fR method. If you are in doubt about a particular status
+variable, it doesn't hurt to localize it. There are five global status
+variables, and the safest way is to localize all five of them:
+.PP
+.Vb 5
+\& sub DESTROY {
+\& local($., $@, $!, $^E, $?);
+\& my $self = shift;
+\& ...;
+\& }
+.Ve
+.PP
+If you define an \f(CW\*(C`AUTOLOAD\*(C'\fR in your class, then Perl will call your
+\&\f(CW\*(C`AUTOLOAD\*(C'\fR to handle the \f(CW\*(C`DESTROY\*(C'\fR method. You can prevent this by
+defining an empty \f(CW\*(C`DESTROY\*(C'\fR, like we did in the autoloading example.
+You can also check the value of \f(CW$AUTOLOAD\fR and return without doing
+anything when called to handle \f(CW\*(C`DESTROY\*(C'\fR.
+.PP
+\fIGlobal Destruction\fR
+.IX Subsection "Global Destruction"
+.PP
+The order in which objects are destroyed during the global destruction
+before the program exits is unpredictable. This means that any objects
+contained by your object may already have been destroyed. You should
+check that a contained object is defined before calling a method on it:
+.PP
+.Vb 2
+\& sub DESTROY {
+\& my $self = shift;
+\&
+\& $self\->{handle}\->close() if $self\->{handle};
+\& }
+.Ve
+.PP
+You can use the \f(CW\*(C`${^GLOBAL_PHASE}\*(C'\fR variable to detect if you are
+currently in the global destruction phase:
+.PP
+.Vb 2
+\& sub DESTROY {
+\& my $self = shift;
+\&
+\& return if ${^GLOBAL_PHASE} eq \*(AqDESTRUCT\*(Aq;
+\&
+\& $self\->{handle}\->close();
+\& }
+.Ve
+.PP
+Note that this variable was added in Perl 5.14.0. If you want to detect
+the global destruction phase on older versions of Perl, you can use the
+\&\f(CW\*(C`Devel::GlobalDestruction\*(C'\fR module on \s-1CPAN.\s0
+.PP
+If your \f(CW\*(C`DESTROY\*(C'\fR method issues a warning during global destruction,
+the Perl interpreter will append the string \*(L" during global
+destruction\*(R" to the warning.
+.PP
+During global destruction, Perl will always garbage collect objects
+before unblessed references. See \*(L"\s-1PERL_DESTRUCT_LEVEL\*(R"\s0 in perlhacktips
+for more information about global destruction.
+.SS "Non-Hash Objects"
+.IX Subsection "Non-Hash Objects"
+All the examples so far have shown objects based on a blessed hash.
+However, it's possible to bless any type of data structure or referent,
+including scalars, globs, and subroutines. You may see this sort of
+thing when looking at code in the wild.
+.PP
+Here's an example of a module as a blessed scalar:
+.PP
+.Vb 1
+\& package Time;
+\&
+\& use v5.36;
+\&
+\& sub new {
+\& my $class = shift;
+\&
+\& my $time = time;
+\& return bless \e$time, $class;
+\& }
+\&
+\& sub epoch {
+\& my $self = shift;
+\& return $$self;
+\& }
+\&
+\& my $time = Time\->new();
+\& print $time\->epoch();
+.Ve
+.SS "Inside-Out objects"
+.IX Subsection "Inside-Out objects"
+In the past, the Perl community experimented with a technique called
+\&\*(L"inside-out objects\*(R". An inside-out object stores its data outside of
+the object's reference, indexed on a unique property of the object,
+such as its memory address, rather than in the object itself. This has
+the advantage of enforcing the encapsulation of object attributes,
+since their data is not stored in the object itself.
+.PP
+This technique was popular for a while (and was recommended in Damian
+Conway's \fIPerl Best Practices\fR), but never achieved universal
+adoption. The Object::InsideOut module on \s-1CPAN\s0 provides a
+comprehensive implementation of this technique, and you may see it or
+other inside-out modules in the wild.
+.PP
+Here is a simple example of the technique, using the
+Hash::Util::FieldHash core module. This module was added to the core
+to support inside-out object implementations.
+.PP
+.Vb 1
+\& package Time;
+\&
+\& use v5.36;
+\&
+\& use Hash::Util::FieldHash \*(Aqfieldhash\*(Aq;
+\&
+\& fieldhash my %time_for;
+\&
+\& sub new {
+\& my $class = shift;
+\&
+\& my $self = bless \e( my $object ), $class;
+\&
+\& $time_for{$self} = time;
+\&
+\& return $self;
+\& }
+\&
+\& sub epoch {
+\& my $self = shift;
+\&
+\& return $time_for{$self};
+\& }
+\&
+\& my $time = Time\->new;
+\& print $time\->epoch;
+.Ve
+.SS "Pseudo-hashes"
+.IX Subsection "Pseudo-hashes"
+The pseudo-hash feature was an experimental feature introduced in
+earlier versions of Perl and removed in 5.10.0. A pseudo-hash is an
+array reference which can be accessed using named keys like a hash. You
+may run in to some code in the wild which uses it. See the fields
+pragma for more information.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+A kinder, gentler tutorial on object-oriented programming in Perl can
+be found in perlootut. You should also check out perlmodlib for
+some style guides on constructing both modules and classes.