summaryrefslogtreecommitdiffstats
path: root/upstream/mageia-cauldron/man1/perlootut.1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
commitfc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch)
treece1e3bce06471410239a6f41282e328770aa404a /upstream/mageia-cauldron/man1/perlootut.1
parentInitial commit. (diff)
downloadmanpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz
manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/mageia-cauldron/man1/perlootut.1')
-rw-r--r--upstream/mageia-cauldron/man1/perlootut.1785
1 files changed, 785 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man1/perlootut.1 b/upstream/mageia-cauldron/man1/perlootut.1
new file mode 100644
index 00000000..4f8fb0e2
--- /dev/null
+++ b/upstream/mageia-cauldron/man1/perlootut.1
@@ -0,0 +1,785 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (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
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. 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 "PERLOOTUT 1"
+.TH PERLOOTUT 1 2023-11-28 "perl v5.38.2" "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
+perlootut \- Object\-Oriented Programming in Perl Tutorial
+.SH DATE
+.IX Header "DATE"
+This document was created in February, 2011, and the last major
+revision was in February, 2013.
+.PP
+If you are reading this in the future then it's possible that the state
+of the art has changed. We recommend you start by reading the perlootut
+document in the latest stable release of Perl, rather than this
+version.
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+This document provides an introduction to object-oriented programming
+in Perl. It begins with a brief overview of the concepts behind object
+oriented design. Then it introduces several different OO systems from
+CPAN <https://www.cpan.org> which build on top of what Perl
+provides.
+.PP
+By default, Perl's built-in OO system is very minimal, leaving you to
+do most of the work. This minimalism made a lot of sense in 1994, but
+in the years since Perl 5.0 we've seen a number of common patterns
+emerge in Perl OO. Fortunately, Perl's flexibility has allowed a rich
+ecosystem of Perl OO systems to flourish.
+.PP
+If you want to know how Perl OO works under the hood, the perlobj
+document explains the nitty gritty details.
+.PP
+This document assumes that you already understand the basics of Perl
+syntax, variable types, operators, and subroutine calls. If you don't
+understand these concepts yet, please read perlintro first. You
+should also read the perlsyn, perlop, and perlsub documents.
+.SH "OBJECT-ORIENTED FUNDAMENTALS"
+.IX Header "OBJECT-ORIENTED FUNDAMENTALS"
+Most object systems share a number of common concepts. You've probably
+heard terms like "class", "object, "method", and "attribute" before.
+Understanding the concepts will make it much easier to read and write
+object-oriented code. If you're already familiar with these terms, you
+should still skim this section, since it explains each concept in terms
+of Perl's OO implementation.
+.PP
+Perl's OO system is class-based. Class-based OO is fairly common. It's
+used by Java, C++, C#, Python, Ruby, and many other languages. There
+are other object orientation paradigms as well. JavaScript is the most
+popular language to use another paradigm. JavaScript's OO system is
+prototype-based.
+.SS Object
+.IX Subsection "Object"
+An \fBobject\fR is a data structure that bundles together data and
+subroutines which operate on that data. An object's data is called
+\&\fBattributes\fR, and its subroutines are called \fBmethods\fR. An object can
+be thought of as a noun (a person, a web service, a computer).
+.PP
+An object represents a single discrete thing. For example, an object
+might represent a file. The attributes for a file object might include
+its path, content, and last modification time. If we created an object
+to represent \fI/etc/hostname\fR on a machine named "foo.example.com",
+that object's path would be "/etc/hostname", its content would be
+"foo\en", and it's last modification time would be 1304974868 seconds
+since the beginning of the epoch.
+.PP
+The methods associated with a file might include \f(CWrename()\fR and
+\&\f(CWwrite()\fR.
+.PP
+In Perl most objects are hashes, but the OO systems we recommend keep
+you from having to worry about this. In practice, it's best to consider
+an object's internal data structure opaque.
+.SS Class
+.IX Subsection "Class"
+A \fBclass\fR defines the behavior of a category of objects. A class is a
+name for a category (like "File"), and a class also defines the
+behavior of objects in that category.
+.PP
+All objects belong to a specific class. For example, our
+\&\fI/etc/hostname\fR object belongs to the \f(CW\*(C`File\*(C'\fR class. When we want to
+create a specific object, we start with its class, and \fBconstruct\fR or
+\&\fBinstantiate\fR an object. A specific object is often referred to as an
+\&\fBinstance\fR of a class.
+.PP
+In Perl, any package can be a class. The difference between a package
+which is a class and one which isn't is based on how the package is
+used. Here's our "class declaration" for the \f(CW\*(C`File\*(C'\fR class:
+.PP
+.Vb 1
+\& package File;
+.Ve
+.PP
+In Perl, there is no special keyword for constructing an object.
+However, most OO modules on CPAN use a method named \f(CWnew()\fR to
+construct a new object:
+.PP
+.Vb 5
+\& my $hostname = File\->new(
+\& path => \*(Aq/etc/hostname\*(Aq,
+\& content => "foo\en",
+\& last_mod_time => 1304974868,
+\& );
+.Ve
+.PP
+(Don't worry about that \f(CW\*(C`\->\*(C'\fR operator, it will be explained
+later.)
+.PP
+\fIBlessing\fR
+.IX Subsection "Blessing"
+.PP
+As we said earlier, most Perl objects are hashes, but an object can be
+an instance of any Perl data type (scalar, array, etc.). Turning a
+plain data structure into an object is done by \fBblessing\fR that data
+structure using Perl's \f(CW\*(C`bless\*(C'\fR function.
+.PP
+While we strongly suggest you don't build your objects from scratch,
+you should know the term \fBbless\fR. A \fBblessed\fR data structure (aka "a
+referent") is an object. We sometimes say that an object has been
+"blessed into a class".
+.PP
+Once a referent has been blessed, the \f(CW\*(C`blessed\*(C'\fR function from the
+Scalar::Util core module can tell us its class name. This subroutine
+returns an object's class when passed an object, and false otherwise.
+.PP
+.Vb 1
+\& use Scalar::Util \*(Aqblessed\*(Aq;
+\&
+\& print blessed($hash); # undef
+\& print blessed($hostname); # File
+.Ve
+.PP
+\fIConstructor\fR
+.IX Subsection "Constructor"
+.PP
+A \fBconstructor\fR creates a new object. In Perl, a class's constructor
+is just another method, unlike some other languages, which provide
+syntax for constructors. Most Perl classes use \f(CW\*(C`new\*(C'\fR as the name for
+their constructor:
+.PP
+.Vb 1
+\& my $file = File\->new(...);
+.Ve
+.SS Methods
+.IX Subsection "Methods"
+You already learned that a \fBmethod\fR is a subroutine that operates on
+an object. You can think of a method as the things that an object can
+\&\fIdo\fR. If an object is a noun, then methods are its verbs (save, print,
+open).
+.PP
+In Perl, methods are simply subroutines that live in a class's package.
+Methods are always written to receive the object as their first
+argument:
+.PP
+.Vb 2
+\& sub print_info {
+\& my $self = shift;
+\&
+\& print "This file is at ", $self\->path, "\en";
+\& }
+\&
+\& $file\->print_info;
+\& # The file is at /etc/hostname
+.Ve
+.PP
+What makes a method special is \fIhow it's called\fR. The arrow operator
+(\f(CW\*(C`\->\*(C'\fR) tells Perl that we are calling a method.
+.PP
+When we make a method call, Perl arranges for the method's \fBinvocant\fR
+to be passed as the first argument. \fBInvocant\fR is a fancy name for the
+thing on the left side of the arrow. The invocant can either be a class
+name or an object. We can also pass additional arguments to the method:
+.PP
+.Vb 3
+\& sub print_info {
+\& my $self = shift;
+\& my $prefix = shift // "This file is at ";
+\&
+\& print $prefix, ", ", $self\->path, "\en";
+\& }
+\&
+\& $file\->print_info("The file is located at ");
+\& # The file is located at /etc/hostname
+.Ve
+.SS Attributes
+.IX Subsection "Attributes"
+Each class can define its \fBattributes\fR. When we instantiate an object,
+we assign values to those attributes. For example, every \f(CW\*(C`File\*(C'\fR object
+has a path. Attributes are sometimes called \fBproperties\fR.
+.PP
+Perl has no special syntax for attributes. Under the hood, attributes
+are often stored as keys in the object's underlying hash, but don't
+worry about this.
+.PP
+We recommend that you only access attributes via \fBaccessor\fR methods.
+These are methods that can get or set the value of each attribute. We
+saw this earlier in the \f(CWprint_info()\fR example, which calls \f(CW\*(C`$self\->path\*(C'\fR.
+.PP
+You might also see the terms \fBgetter\fR and \fBsetter\fR. These are two
+types of accessors. A getter gets the attribute's value, while a setter
+sets it. Another term for a setter is \fBmutator\fR
+.PP
+Attributes are typically defined as read-only or read-write. Read-only
+attributes can only be set when the object is first created, while
+read-write attributes can be altered at any time.
+.PP
+The value of an attribute may itself be another object. For example,
+instead of returning its last mod time as a number, the \f(CW\*(C`File\*(C'\fR class
+could return a DateTime object representing that value.
+.PP
+It's possible to have a class that does not expose any publicly
+settable attributes. Not every class has attributes and methods.
+.SS Polymorphism
+.IX Subsection "Polymorphism"
+\&\fBPolymorphism\fR is a fancy way of saying that objects from two
+different classes share an API. For example, we could have \f(CW\*(C`File\*(C'\fR and
+\&\f(CW\*(C`WebPage\*(C'\fR classes which both have a \f(CWprint_content()\fR method. This
+method might produce different output for each class, but they share a
+common interface.
+.PP
+While the two classes may differ in many ways, when it comes to the
+\&\f(CWprint_content()\fR method, they are the same. This means that we can
+try to call the \f(CWprint_content()\fR method on an object of either class,
+and \fBwe don't have to know what class the object belongs to!\fR
+.PP
+Polymorphism is one of the key concepts of object-oriented design.
+.SS Inheritance
+.IX Subsection "Inheritance"
+\&\fBInheritance\fR lets you create a specialized version of an existing
+class. Inheritance lets the new class reuse the methods and attributes
+of another class.
+.PP
+For example, we could create an \f(CW\*(C`File::MP3\*(C'\fR class which \fBinherits\fR
+from \f(CW\*(C`File\*(C'\fR. An \f(CW\*(C`File::MP3\*(C'\fR \fBis-a\fR \fImore specific\fR type of \f(CW\*(C`File\*(C'\fR.
+All mp3 files are files, but not all files are mp3 files.
+.PP
+We often refer to inheritance relationships as \fBparent-child\fR or
+\&\f(CW\*(C`superclass\*(C'\fR/\f(CW\*(C`subclass\*(C'\fR relationships. Sometimes we say that the
+child has an \fBis-a\fR relationship with its parent class.
+.PP
+\&\f(CW\*(C`File\*(C'\fR is a \fBsuperclass\fR of \f(CW\*(C`File::MP3\*(C'\fR, and \f(CW\*(C`File::MP3\*(C'\fR is a
+\&\fBsubclass\fR of \f(CW\*(C`File\*(C'\fR.
+.PP
+.Vb 1
+\& package File::MP3;
+\&
+\& use parent \*(AqFile\*(Aq;
+.Ve
+.PP
+The parent module is one of several ways that Perl lets you define
+inheritance relationships.
+.PP
+Perl allows multiple inheritance, which means that a class can inherit
+from multiple parents. While this is possible, we strongly recommend
+against it. Generally, you can use \fBroles\fR to do everything you can do
+with multiple inheritance, but in a cleaner way.
+.PP
+Note that there's nothing wrong with defining multiple subclasses of a
+given class. This is both common and safe. For example, we might define
+\&\f(CW\*(C`File::MP3::FixedBitrate\*(C'\fR and \f(CW\*(C`File::MP3::VariableBitrate\*(C'\fR classes to
+distinguish between different types of mp3 file.
+.PP
+\fIOverriding methods and method resolution\fR
+.IX Subsection "Overriding methods and method resolution"
+.PP
+Inheritance allows two classes to share code. By default, every method
+in the parent class is also available in the child. The child can
+explicitly \fBoverride\fR a parent's method to provide its own
+implementation. For example, if we have an \f(CW\*(C`File::MP3\*(C'\fR object, it has
+the \f(CWprint_info()\fR method from \f(CW\*(C`File\*(C'\fR:
+.PP
+.Vb 6
+\& my $cage = File::MP3\->new(
+\& path => \*(Aqmp3s/My\-Body\-Is\-a\-Cage.mp3\*(Aq,
+\& content => $mp3_data,
+\& last_mod_time => 1304974868,
+\& title => \*(AqMy Body Is a Cage\*(Aq,
+\& );
+\&
+\& $cage\->print_info;
+\& # The file is at mp3s/My\-Body\-Is\-a\-Cage.mp3
+.Ve
+.PP
+If we wanted to include the mp3's title in the greeting, we could
+override the method:
+.PP
+.Vb 1
+\& package File::MP3;
+\&
+\& use parent \*(AqFile\*(Aq;
+\&
+\& sub print_info {
+\& my $self = shift;
+\&
+\& print "This file is at ", $self\->path, "\en";
+\& print "Its title is ", $self\->title, "\en";
+\& }
+\&
+\& $cage\->print_info;
+\& # The file is at mp3s/My\-Body\-Is\-a\-Cage.mp3
+\& # Its title is My Body Is a Cage
+.Ve
+.PP
+The process of determining what method should be used is called
+\&\fBmethod resolution\fR. What Perl does is look at the object's class
+first (\f(CW\*(C`File::MP3\*(C'\fR in this case). If that class defines the method,
+then that class's version of the method is called. If not, Perl looks
+at each parent class in turn. For \f(CW\*(C`File::MP3\*(C'\fR, its only parent is
+\&\f(CW\*(C`File\*(C'\fR. If \f(CW\*(C`File::MP3\*(C'\fR does not define the method, but \f(CW\*(C`File\*(C'\fR does,
+then Perl calls the method in \f(CW\*(C`File\*(C'\fR.
+.PP
+If \f(CW\*(C`File\*(C'\fR inherited from \f(CW\*(C`DataSource\*(C'\fR, which inherited from \f(CW\*(C`Thing\*(C'\fR,
+then Perl would keep looking "up the chain" if necessary.
+.PP
+It is possible to explicitly call a parent method from a child:
+.PP
+.Vb 1
+\& package File::MP3;
+\&
+\& use parent \*(AqFile\*(Aq;
+\&
+\& sub print_info {
+\& my $self = shift;
+\&
+\& $self\->SUPER::print_info();
+\& print "Its title is ", $self\->title, "\en";
+\& }
+.Ve
+.PP
+The \f(CW\*(C`SUPER::\*(C'\fR bit tells Perl to look for the \f(CWprint_info()\fR in the
+\&\f(CW\*(C`File::MP3\*(C'\fR class's inheritance chain. When it finds the parent class
+that implements this method, the method is called.
+.PP
+We mentioned multiple inheritance earlier. The main problem with
+multiple inheritance is that it greatly complicates method resolution.
+See perlobj for more details.
+.SS Encapsulation
+.IX Subsection "Encapsulation"
+\&\fBEncapsulation\fR is the idea that an object is opaque. When another
+developer uses your class, they don't need to know \fIhow\fR it is
+implemented, they just need to know \fIwhat\fR it does.
+.PP
+Encapsulation is important for several reasons. First, it allows you to
+separate the public API from the private implementation. This means you
+can change that implementation without breaking the API.
+.PP
+Second, when classes are well encapsulated, they become easier to
+subclass. Ideally, a subclass uses the same APIs to access object data
+that its parent class uses. In reality, subclassing sometimes involves
+violating encapsulation, but a good API can minimize the need to do
+this.
+.PP
+We mentioned earlier that most Perl objects are implemented as hashes
+under the hood. The principle of encapsulation tells us that we should
+not rely on this. Instead, we should use accessor methods to access the
+data in that hash. The object systems that we recommend below all
+automate the generation of accessor methods. If you use one of them,
+you should never have to access the object as a hash directly.
+.SS Composition
+.IX Subsection "Composition"
+In object-oriented code, we often find that one object references
+another object. This is called \fBcomposition\fR, or a \fBhas-a\fR
+relationship.
+.PP
+Earlier, we mentioned that the \f(CW\*(C`File\*(C'\fR class's \f(CW\*(C`last_mod_time\*(C'\fR
+accessor could return a DateTime object. This is a perfect example
+of composition. We could go even further, and make the \f(CW\*(C`path\*(C'\fR and
+\&\f(CW\*(C`content\*(C'\fR accessors return objects as well. The \f(CW\*(C`File\*(C'\fR class would
+then be \fBcomposed\fR of several other objects.
+.SS Roles
+.IX Subsection "Roles"
+\&\fBRoles\fR are something that a class \fIdoes\fR, rather than something that
+it \fIis\fR. Roles are relatively new to Perl, but have become rather
+popular. Roles are \fBapplied\fR to classes. Sometimes we say that classes
+\&\fBconsume\fR roles.
+.PP
+Roles are an alternative to inheritance for providing polymorphism.
+Let's assume we have two classes, \f(CW\*(C`Radio\*(C'\fR and \f(CW\*(C`Computer\*(C'\fR. Both of
+these things have on/off switches. We want to model that in our class
+definitions.
+.PP
+We could have both classes inherit from a common parent, like
+\&\f(CW\*(C`Machine\*(C'\fR, but not all machines have on/off switches. We could create
+a parent class called \f(CW\*(C`HasOnOffSwitch\*(C'\fR, but that is very artificial.
+Radios and computers are not specializations of this parent. This
+parent is really a rather ridiculous creation.
+.PP
+This is where roles come in. It makes a lot of sense to create a
+\&\f(CW\*(C`HasOnOffSwitch\*(C'\fR role and apply it to both classes. This role would
+define a known API like providing \f(CWturn_on()\fR and \f(CWturn_off()\fR
+methods.
+.PP
+Perl does not have any built-in way to express roles. In the past,
+people just bit the bullet and used multiple inheritance. Nowadays,
+there are several good choices on CPAN for using roles.
+.SS "When to Use OO"
+.IX Subsection "When to Use OO"
+Object Orientation is not the best solution to every problem. In \fIPerl
+Best Practices\fR (copyright 2004, Published by O'Reilly Media, Inc.),
+Damian Conway provides a list of criteria to use when deciding if OO is
+the right fit for your problem:
+.IP \(bu 4
+The system being designed is large, or is likely to become large.
+.IP \(bu 4
+The data can be aggregated into obvious structures, especially if
+there's a large amount of data in each aggregate.
+.IP \(bu 4
+The various types of data aggregate form a natural hierarchy that
+facilitates the use of inheritance and polymorphism.
+.IP \(bu 4
+You have a piece of data on which many different operations are
+applied.
+.IP \(bu 4
+You need to perform the same general operations on related types of
+data, but with slight variations depending on the specific type of data
+the operations are applied to.
+.IP \(bu 4
+It's likely you'll have to add new data types later.
+.IP \(bu 4
+The typical interactions between pieces of data are best represented by
+operators.
+.IP \(bu 4
+The implementation of individual components of the system is likely to
+change over time.
+.IP \(bu 4
+The system design is already object-oriented.
+.IP \(bu 4
+Large numbers of other programmers will be using your code modules.
+.SH "PERL OO SYSTEMS"
+.IX Header "PERL OO SYSTEMS"
+As we mentioned before, Perl's built-in OO system is very minimal, but
+also quite flexible. Over the years, many people have developed systems
+which build on top of Perl's built-in system to provide more features
+and convenience.
+.PP
+We strongly recommend that you use one of these systems. Even the most
+minimal of them eliminates a lot of repetitive boilerplate. There's
+really no good reason to write your classes from scratch in Perl.
+.PP
+If you are interested in the guts underlying these systems, check out
+perlobj.
+.SS Moose
+.IX Subsection "Moose"
+Moose bills itself as a "postmodern object system for Perl 5". Don't
+be scared, the "postmodern" label is a callback to Larry's description
+of Perl as "the first postmodern computer language".
+.PP
+\&\f(CW\*(C`Moose\*(C'\fR provides a complete, modern OO system. Its biggest influence
+is the Common Lisp Object System, but it also borrows ideas from
+Smalltalk and several other languages. \f(CW\*(C`Moose\*(C'\fR was created by Stevan
+Little, and draws heavily from his work on the Raku OO design.
+.PP
+Here is our \f(CW\*(C`File\*(C'\fR class using \f(CW\*(C`Moose\*(C'\fR:
+.PP
+.Vb 2
+\& package File;
+\& use Moose;
+\&
+\& has path => ( is => \*(Aqro\*(Aq );
+\& has content => ( is => \*(Aqro\*(Aq );
+\& has last_mod_time => ( is => \*(Aqro\*(Aq );
+\&
+\& sub print_info {
+\& my $self = shift;
+\&
+\& print "This file is at ", $self\->path, "\en";
+\& }
+.Ve
+.PP
+\&\f(CW\*(C`Moose\*(C'\fR provides a number of features:
+.IP \(bu 4
+Declarative sugar
+.Sp
+\&\f(CW\*(C`Moose\*(C'\fR provides a layer of declarative "sugar" for defining classes.
+That sugar is just a set of exported functions that make declaring how
+your class works simpler and more palatable. This lets you describe
+\&\fIwhat\fR your class is, rather than having to tell Perl \fIhow\fR to
+implement your class.
+.Sp
+The \f(CWhas()\fR subroutine declares an attribute, and \f(CW\*(C`Moose\*(C'\fR
+automatically creates accessors for these attributes. It also takes
+care of creating a \f(CWnew()\fR method for you. This constructor knows
+about the attributes you declared, so you can set them when creating a
+new \f(CW\*(C`File\*(C'\fR.
+.IP \(bu 4
+Roles built-in
+.Sp
+\&\f(CW\*(C`Moose\*(C'\fR lets you define roles the same way you define classes:
+.Sp
+.Vb 2
+\& package HasOnOffSwitch;
+\& use Moose::Role;
+\&
+\& has is_on => (
+\& is => \*(Aqrw\*(Aq,
+\& isa => \*(AqBool\*(Aq,
+\& );
+\&
+\& sub turn_on {
+\& my $self = shift;
+\& $self\->is_on(1);
+\& }
+\&
+\& sub turn_off {
+\& my $self = shift;
+\& $self\->is_on(0);
+\& }
+.Ve
+.IP \(bu 4
+A miniature type system
+.Sp
+In the example above, you can see that we passed \f(CW\*(C`isa => \*(AqBool\*(Aq\*(C'\fR
+to \f(CWhas()\fR when creating our \f(CW\*(C`is_on\*(C'\fR attribute. This tells \f(CW\*(C`Moose\*(C'\fR
+that this attribute must be a boolean value. If we try to set it to an
+invalid value, our code will throw an error.
+.IP \(bu 4
+Full introspection and manipulation
+.Sp
+Perl's built-in introspection features are fairly minimal. \f(CW\*(C`Moose\*(C'\fR
+builds on top of them and creates a full introspection layer for your
+classes. This lets you ask questions like "what methods does the File
+class implement?" It also lets you modify your classes
+programmatically.
+.IP \(bu 4
+Self-hosted and extensible
+.Sp
+\&\f(CW\*(C`Moose\*(C'\fR describes itself using its own introspection API. Besides
+being a cool trick, this means that you can extend \f(CW\*(C`Moose\*(C'\fR using
+\&\f(CW\*(C`Moose\*(C'\fR itself.
+.IP \(bu 4
+Rich ecosystem
+.Sp
+There is a rich ecosystem of \f(CW\*(C`Moose\*(C'\fR extensions on CPAN under the
+MooseX <https://metacpan.org/search?q=MooseX>
+namespace. In addition, many modules on CPAN already use \f(CW\*(C`Moose\*(C'\fR,
+providing you with lots of examples to learn from.
+.IP \(bu 4
+Many more features
+.Sp
+\&\f(CW\*(C`Moose\*(C'\fR is a very powerful tool, and we can't cover all of its
+features here. We encourage you to learn more by reading the \f(CW\*(C`Moose\*(C'\fR
+documentation, starting with
+Moose::Manual <https://metacpan.org/pod/Moose::Manual>.
+.PP
+Of course, \f(CW\*(C`Moose\*(C'\fR isn't perfect.
+.PP
+\&\f(CW\*(C`Moose\*(C'\fR can make your code slower to load. \f(CW\*(C`Moose\*(C'\fR itself is not
+small, and it does a \fIlot\fR of code generation when you define your
+class. This code generation means that your runtime code is as fast as
+it can be, but you pay for this when your modules are first loaded.
+.PP
+This load time hit can be a problem when startup speed is important,
+such as with a command-line script or a "plain vanilla" CGI script that
+must be loaded each time it is executed.
+.PP
+Before you panic, know that many people do use \f(CW\*(C`Moose\*(C'\fR for
+command-line tools and other startup-sensitive code. We encourage you
+to try \f(CW\*(C`Moose\*(C'\fR out first before worrying about startup speed.
+.PP
+\&\f(CW\*(C`Moose\*(C'\fR also has several dependencies on other modules. Most of these
+are small stand-alone modules, a number of which have been spun off
+from \f(CW\*(C`Moose\*(C'\fR. \f(CW\*(C`Moose\*(C'\fR itself, and some of its dependencies, require a
+compiler. If you need to install your software on a system without a
+compiler, or if having \fIany\fR dependencies is a problem, then \f(CW\*(C`Moose\*(C'\fR
+may not be right for you.
+.PP
+\fIMoo\fR
+.IX Subsection "Moo"
+.PP
+If you try \f(CW\*(C`Moose\*(C'\fR and find that one of these issues is preventing you
+from using \f(CW\*(C`Moose\*(C'\fR, we encourage you to consider Moo next. \f(CW\*(C`Moo\*(C'\fR
+implements a subset of \f(CW\*(C`Moose\*(C'\fR's functionality in a simpler package.
+For most features that it does implement, the end-user API is
+\&\fIidentical\fR to \f(CW\*(C`Moose\*(C'\fR, meaning you can switch from \f(CW\*(C`Moo\*(C'\fR to
+\&\f(CW\*(C`Moose\*(C'\fR quite easily.
+.PP
+\&\f(CW\*(C`Moo\*(C'\fR does not implement most of \f(CW\*(C`Moose\*(C'\fR's introspection API, so it's
+often faster when loading your modules. Additionally, none of its
+dependencies require XS, so it can be installed on machines without a
+compiler.
+.PP
+One of \f(CW\*(C`Moo\*(C'\fR's most compelling features is its interoperability with
+\&\f(CW\*(C`Moose\*(C'\fR. When someone tries to use \f(CW\*(C`Moose\*(C'\fR's introspection API on a
+\&\f(CW\*(C`Moo\*(C'\fR class or role, it is transparently inflated into a \f(CW\*(C`Moose\*(C'\fR
+class or role. This makes it easier to incorporate \f(CW\*(C`Moo\*(C'\fR\-using code
+into a \f(CW\*(C`Moose\*(C'\fR code base and vice versa.
+.PP
+For example, a \f(CW\*(C`Moose\*(C'\fR class can subclass a \f(CW\*(C`Moo\*(C'\fR class using
+\&\f(CW\*(C`extends\*(C'\fR or consume a \f(CW\*(C`Moo\*(C'\fR role using \f(CW\*(C`with\*(C'\fR.
+.PP
+The \f(CW\*(C`Moose\*(C'\fR authors hope that one day \f(CW\*(C`Moo\*(C'\fR can be made obsolete by
+improving \f(CW\*(C`Moose\*(C'\fR enough, but for now it provides a worthwhile
+alternative to \f(CW\*(C`Moose\*(C'\fR.
+.SS Class::Accessor
+.IX Subsection "Class::Accessor"
+Class::Accessor is the polar opposite of \f(CW\*(C`Moose\*(C'\fR. It provides very
+few features, nor is it self-hosting.
+.PP
+It is, however, very simple, pure Perl, and it has no non-core
+dependencies. It also provides a "Moose-like" API on demand for the
+features it supports.
+.PP
+Even though it doesn't do much, it is still preferable to writing your
+own classes from scratch.
+.PP
+Here's our \f(CW\*(C`File\*(C'\fR class with \f(CW\*(C`Class::Accessor\*(C'\fR:
+.PP
+.Vb 2
+\& package File;
+\& use Class::Accessor \*(Aqantlers\*(Aq;
+\&
+\& has path => ( is => \*(Aqro\*(Aq );
+\& has content => ( is => \*(Aqro\*(Aq );
+\& has last_mod_time => ( is => \*(Aqro\*(Aq );
+\&
+\& sub print_info {
+\& my $self = shift;
+\&
+\& print "This file is at ", $self\->path, "\en";
+\& }
+.Ve
+.PP
+The \f(CW\*(C`antlers\*(C'\fR import flag tells \f(CW\*(C`Class::Accessor\*(C'\fR that you want to
+define your attributes using \f(CW\*(C`Moose\*(C'\fR\-like syntax. The only parameter
+that you can pass to \f(CW\*(C`has\*(C'\fR is \f(CW\*(C`is\*(C'\fR. We recommend that you use this
+Moose-like syntax if you choose \f(CW\*(C`Class::Accessor\*(C'\fR since it means you
+will have a smoother upgrade path if you later decide to move to
+\&\f(CW\*(C`Moose\*(C'\fR.
+.PP
+Like \f(CW\*(C`Moose\*(C'\fR, \f(CW\*(C`Class::Accessor\*(C'\fR generates accessor methods and a
+constructor for your class.
+.SS Class::Tiny
+.IX Subsection "Class::Tiny"
+Finally, we have Class::Tiny. This module truly lives up to its
+name. It has an incredibly minimal API and absolutely no dependencies
+on any recent Perl. Still, we think it's a lot easier to use than
+writing your own OO code from scratch.
+.PP
+Here's our \f(CW\*(C`File\*(C'\fR class once more:
+.PP
+.Vb 2
+\& package File;
+\& use Class::Tiny qw( path content last_mod_time );
+\&
+\& sub print_info {
+\& my $self = shift;
+\&
+\& print "This file is at ", $self\->path, "\en";
+\& }
+.Ve
+.PP
+That's it!
+.PP
+With \f(CW\*(C`Class::Tiny\*(C'\fR, all accessors are read-write. It generates a
+constructor for you, as well as the accessors you define.
+.PP
+You can also use Class::Tiny::Antlers for \f(CW\*(C`Moose\*(C'\fR\-like syntax.
+.SS Role::Tiny
+.IX Subsection "Role::Tiny"
+As we mentioned before, roles provide an alternative to inheritance,
+but Perl does not have any built-in role support. If you choose to use
+Moose, it comes with a full-fledged role implementation. However, if
+you use one of our other recommended OO modules, you can still use
+roles with Role::Tiny
+.PP
+\&\f(CW\*(C`Role::Tiny\*(C'\fR provides some of the same features as Moose's role
+system, but in a much smaller package. Most notably, it doesn't support
+any sort of attribute declaration, so you have to do that by hand.
+Still, it's useful, and works well with \f(CW\*(C`Class::Accessor\*(C'\fR and
+\&\f(CW\*(C`Class::Tiny\*(C'\fR
+.SS "OO System Summary"
+.IX Subsection "OO System Summary"
+Here's a brief recap of the options we covered:
+.IP \(bu 4
+Moose
+.Sp
+\&\f(CW\*(C`Moose\*(C'\fR is the maximal option. It has a lot of features, a big
+ecosystem, and a thriving user base. We also covered Moo briefly.
+\&\f(CW\*(C`Moo\*(C'\fR is \f(CW\*(C`Moose\*(C'\fR lite, and a reasonable alternative when Moose
+doesn't work for your application.
+.IP \(bu 4
+Class::Accessor
+.Sp
+\&\f(CW\*(C`Class::Accessor\*(C'\fR does a lot less than \f(CW\*(C`Moose\*(C'\fR, and is a nice
+alternative if you find \f(CW\*(C`Moose\*(C'\fR overwhelming. It's been around a long
+time and is well battle-tested. It also has a minimal \f(CW\*(C`Moose\*(C'\fR
+compatibility mode which makes moving from \f(CW\*(C`Class::Accessor\*(C'\fR to
+\&\f(CW\*(C`Moose\*(C'\fR easy.
+.IP \(bu 4
+Class::Tiny
+.Sp
+\&\f(CW\*(C`Class::Tiny\*(C'\fR is the absolute minimal option. It has no dependencies,
+and almost no syntax to learn. It's a good option for a super minimal
+environment and for throwing something together quickly without having
+to worry about details.
+.IP \(bu 4
+Role::Tiny
+.Sp
+Use \f(CW\*(C`Role::Tiny\*(C'\fR with \f(CW\*(C`Class::Accessor\*(C'\fR or \f(CW\*(C`Class::Tiny\*(C'\fR if you find
+yourself considering multiple inheritance. If you go with \f(CW\*(C`Moose\*(C'\fR, it
+comes with its own role implementation.
+.SS "Other OO Systems"
+.IX Subsection "Other OO Systems"
+There are literally dozens of other OO-related modules on CPAN besides
+those covered here, and you're likely to run across one or more of them
+if you work with other people's code.
+.PP
+In addition, plenty of code in the wild does all of its OO "by hand",
+using just the Perl built-in OO features. If you need to maintain such
+code, you should read perlobj to understand exactly how Perl's
+built-in OO works.
+.SH CONCLUSION
+.IX Header "CONCLUSION"
+As we said before, Perl's minimal OO system has led to a profusion of
+OO systems on CPAN. While you can still drop down to the bare metal and
+write your classes by hand, there's really no reason to do that with
+modern Perl.
+.PP
+For small systems, Class::Tiny and Class::Accessor both provide
+minimal object systems that take care of basic boilerplate for you.
+.PP
+For bigger projects, Moose provides a rich set of features that will
+let you focus on implementing your business logic. Moo provides a
+nice alternative to Moose when you want a lot of features but need
+faster compile time or to avoid XS.
+.PP
+We encourage you to play with and evaluate Moose, Moo,
+Class::Accessor, and Class::Tiny to see which OO system is right
+for you.