This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perldelta for dd2a7f9048
[perl5.git] / pod / perlootut.pod
index 062706d..e494f23 100644 (file)
@@ -10,7 +10,13 @@ perlootut - Object-Oriented Programming in Perl Tutorial
 
 =head1 DATE
 
-This document was created in February, 2011.
+This document was created in February, 2011, and the last major
+revision was in February, 2013.
+
+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.
 
 =head1 DESCRIPTION
 
@@ -56,46 +62,47 @@ subroutines which operate on that data. An object's data is called
 B<attributes>, and its subroutines are called B<methods>. An object can
 be thought of as a noun (a person, a web service, a computer).
 
-An object represents a single discrete thing. For example, an
-object might represent a person. The attributes for a person object
-might include name, birth date, and country of residence. If we created
-an object to represent Larry Wall, Perl's creator, that object's name
-would be "Larry Wall", born on "September 27, 1954", and living in
-"USA".
+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 F</etc/hostname> on a machine named "foo.example.com",
+that object's path would be "/etc/hostname", its content would be
+"foo\n", and it's last modification time would be 1304974868 seconds
+since the beginning of the epoch.
 
-The methods associated with a person might include C<print_greeting()>
-and C<calculate_age()>.
+The methods associated with a file might include C<rename()> and
+C<write()>.
 
-In Perl most objects are hash references, 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.
+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.
 
 =head2 Class
 
 A B<class> defines the behavior of a category of objects. A class is a
-name for a category (like "Person"), and a class also defines the
+name for a category (like "File"), and a class also defines the
 behavior of objects in that category.
 
-All objects belong to a specific class. For example, our Larry Wall
-object belongs to the C<Person> class. When we want to create a
-specific object, we start with its class, and B<construct> or
+All objects belong to a specific class. For example, our
+F</etc/hostname> object belongs to the C<File> class. When we want to
+create a specific object, we start with its class, and B<construct> or
 B<instantiate> an object. A specific object is often referred to as an
 B<instance> of a class.
 
 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 Person class:
+used. Here's our "class declaration" for the C<File> class:
 
-  package Person;
+  package File;
 
 In Perl, there is no special keyword for constructing an object.
 However, most OO modules on CPAN use a method named C<new()> to
 construct a new object:
 
-  my $larry = Person->new(
-      name         => 'Larry Wall',
-      birth_date   => '1954-09-27',
-      country_code => 'us',
+  my $hostname = File->new(
+      path          => '/etc/hostname',
+      content       => "foo\n",
+      last_mod_time => 1304974868,
   );
 
 (Don't worry about that C<< -> >> operator, it will be explained
@@ -103,23 +110,24 @@ later.)
 
 =head3 Blessing
 
-As we said earlier, most Perl objects are hash references, but an
-object can be a reference to any Perl data type (scalar, array, etc.).
-Turning a plain reference into an object is done by B<blessing> that
-reference using Perl's C<bless> function.
+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 B<blessing> that data
+structure using Perl's C<bless> function.
 
 While we strongly suggest you don't build your objects from scratch,
-you should know the term B<bless>. A B<blessed> reference is an object.
-We sometimes say that an object has been "blessed into a class".
+you should know the term B<bless>. A B<blessed> data structure (aka "a
+referent") is an object. We sometimes say that an object has been
+"blessed into a class".
 
-Once a reference has been blessed, the C<blessed> function from the
+Once a referent has been blessed, the C<blessed> function from the
 L<Scalar::Util> core module can tell us its class name. This subroutine
 returns an object's class when passed an object, and false otherwise.
 
   use Scalar::Util 'blessed';
 
-  print blessed($hash);   # undef
-  print blessed($larry);  # Person
+  print blessed($hash);      # undef
+  print blessed($hostname);  # File
 
 =head3 Constructor
 
@@ -128,25 +136,27 @@ is just another method, unlike some other languages, which provide
 syntax for constructors. Most Perl classes use C<new> as the name for
 their constructor:
 
-  my $file = File->new();
+  my $file = File->new(...);
 
 =head2 Methods
 
 You already learned that a B<method> is a subroutine that operates on
-an object's data. You can think of a method as the things that an
-object can I<do>.
+an object. You can think of a method as the things that an object can
+I<do>. If an object is a noun, then methods are its verbs (save, print,
+open).
 
 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:
 
-  sub print_greeting {
+  sub print_info {
       my $self = shift;
 
-      print "Hello, ", $self->name, "\n";
+      print "This file is at ", $self->path, "\n";
   }
 
-  $larry->print_greeting; # Hello, Larry Wall
+  $file->print_info;
+  # The file is at /etc/hostname
 
 What makes a method special is I<how it's called>. The arrow operator
 (C<< -> >>) tells Perl that we are calling a method.
@@ -156,41 +166,42 @@ to be passed as the first argument. B<Invocant> 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:
 
-  sub print_greeting {
-      my $self     = shift;
-      my $greeting = shift // "Hello";
+  sub print_info {
+      my $self   = shift;
+      my $prefix = shift // "This file is at ";
 
-      print $greeting, ", ", $self->name, "\n";
+      print $prefix, ", ", $self->path, "\n";
   }
 
-  $larry->print_greeting("Yo, Wassup"); # Yo, Wassup, Larry Wall
+  $file->print_info("The file is located at ");
+  # The file is located at /etc/hostname
 
 =head2 Attributes
 
 Each class can define its B<attributes>. When we instantiate an object,
-we assign values to those attributes. For example, every C<Person>
-object has a name. Attributes are sometimes called B<properties>.
+we assign values to those attributes. For example, every C<File> object
+has a path. Attributes are sometimes called B<properties>.
 
 Perl has no special syntax for attributes. Under the hood, attributes
-are often stored as keys in the object's hash reference, but don't
+are often stored as keys in the object's underlying hash, but don't
 worry about this.
 
 We recommend that you only access attributes via B<accessor> methods.
 These are methods that can get or set the value of each attribute. We
-saw this earlier in the C<print_greeting()> example, which calls C<<
-$self->name >>.
+saw this earlier in the C<print_info()> example, which calls C<<
+$self->path >>.
 
 You might also see the terms B<getter> and B<setter>. These are two
 types of accessors. A getter gets the attribute's value, while a setter
-sets it.
+sets it. Another term for a setter is B<mutator>
 
 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.
 
 The value of an attribute may itself be another object. For example,
-instead of returning its birth date as a string, the C<Person> class
-could return a L<DateTime> object representing that date.
+instead of returning its last mod time as a number, the C<File> class
+could return a L<DateTime> object representing that value.
 
 It's possible to have a class that does not expose any publicly
 settable attributes. Not every class has attributes and methods.
@@ -198,39 +209,38 @@ settable attributes. Not every class has attributes and methods.
 =head2 Polymorphism
 
 B<Polymorphism> is a fancy way of saying that objects from two
-different classes share an API. For example, we could have C<Person>
-and C<Animal> classes which both have a C<speak()> method. This method
-might produce different output for each class, but the basic API is the
-same.
+different classes share an API. For example, we could have C<File> and
+C<WebPage> classes which both have a C<print_content()> method. This
+method might produce different output for each class, but they share a
+common interface.
 
 While the two classes may differ in many ways, when it comes to the
-C<speak()> method, they are the same. This means that we can try to
-call the C<speak()> method on an object of either class, and B<we don't
-have to know what class the object belongs to!>
+C<print_content()> method, they are the same. This means that we can
+try to call the C<print_content()> method on an object of either class,
+and B<we don't have to know what class the object belongs to!>
 
 Polymorphism is one of the key concepts of object-oriented design.
 
 =head2 Inheritance
 
-B<Inheritance> is a way to specialize an existing class. It allows one
-class to reuse the methods and attributes of another class.
+B<Inheritance> lets you create a specialized version of an existing
+class. Inheritance lets the new class reuse the methods and attributes
+of another class.
 
-We often refer to inheritance relationships as B<parent-child> or
-C<superclass/subclass> relationships. Sometimes this is called an
-B<is-a> relationship.
+For example, we could create an C<File::MP3> class which B<inherits>
+from C<File>. An C<File::MP3> B<is-a> I<more specific> type of C<File>.
+All mp3 files are files, but not all files are mp3 files.
 
-Inheritance is best used to create a specialized version of a class.
-For example, we could create an C<Employee> class which B<inherits>
-from C<Person>. An C<Employee> B<is-a> I<more specific> type of
-C<Person>. All employees are persons, but not all persons are
-employees.
+We often refer to inheritance relationships as B<parent-child> or
+C<superclass/subclass> relationships. Sometimes we say that the child
+has an B<is-a> relationship with its parent class.
 
-C<Person> is a B<superclass> of C<Employee>, and C<Employee> is a
-B<subclass> of C<Person>.
+C<File> is a B<superclass> of C<File::MP3>, and C<File::MP3> is a
+B<subclass> of C<File>.
 
-  package Employee;
+  package File::MP3;
 
-  use parent 'Person';
+  use parent 'File';
 
 The L<parent> module is one of several ways that Perl lets you define
 inheritance relationships.
@@ -238,73 +248,76 @@ inheritance relationships.
 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 B<roles> to do everything you can do
-with multiple inheritance in a cleaner way.
+with multiple inheritance, but in a cleaner way.
 
 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
-C<Employee::Permanent> and C<Employee::Temporary> classes to
-distinguish between different types of employees.
+C<File::MP3::FixedBitrate> and C<File::MP3::VariableBitrate> classes to
+distinguish between different types of mp3 file.
 
 =head3 Overriding methods and method resolution
 
 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 B<override> a parent's method to provide its own
-implementation. For example, if we have an C<Employee> object, it has
-the C<print_greeting()> method from person:
-
-  my $larry = Employee->new(
-      name         => 'Larry Wall',
-      birth_date   => '1954-09-27',
-      country_code => 'us',
-      job_title    => 'Hacker Extraordinaire',
+implementation. For example, if we have an C<File::MP3> object, it has
+the C<print_info()> method from C<File>:
+
+  my $cage = File::MP3->new(
+      path          => 'mp3s/My-Body-Is-a-Cage.mp3',
+      content       => $mp3_data,
+      last_mod_time => 1304974868,
+      title         => 'My Body Is a Cage',
   );
 
-  $larry->print_greeting; # Hello, Larry Wall
+  $cage->print_info;
+  # The file is at mp3s/My-Body-Is-a-Cage.mp3
 
-If we wanted to include the employee's job title in the greeting, we
-could override the method:
+If we wanted to include the mp3's title in the greeting, we could
+override the method:
 
-  package Employee;
+  package File::MP3;
 
-  use parent 'Person';
+  use parent 'File';
 
-  sub print_greeting {
+  sub print_info {
       my $self = shift;
 
-      print "Hello, ", $self->name, " - ", $self->job_title, "\n";
+      print "This file is at ", $self->path, "\n";
+      print "Its title is ", $self->title, "\n";
   }
 
-  $larry->print_greeting; # Hello, Larry Wall - Hacker Extraordinaire
+  $cage->print_info;
+  # The file is at mp3s/My-Body-Is-a-Cage.mp3
+  # Its title is My Body Is a Cage
 
 The process of determining what method should be used is called
 B<method resolution>. What Perl does is look at the object's class
-first (C<Employee> in this case). If that class defines the method,
+first (C<File::MP3> 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 C<Employee>, its only parent is
-C<Person>. If C<Employee> does not define the method, but C<Person>
-does, then Perl calls the method in C<Person>.
+at each parent class in turn. For C<File::MP3>, its only parent is
+C<File>. If C<File::MP3> does not define the method, but C<File> does,
+then Perl calls the method in C<File>.
 
-If C<Person> inherited from C<Animal>, which inherited from C<Thing>,
+If C<File> inherited from C<DataSource>, which inherited from C<Thing>,
 then Perl would keep looking "up the chain" if necessary.
 
 It is possible to explicitly call a parent method from a child:
 
-  package Employee;
+  package File::MP3;
 
-  use parent 'Person';
+  use parent 'File';
 
-  sub print_greeting {
+  sub print_info {
       my $self = shift;
 
-      $self->SUPER::print_greeting();
-
-      print "Your job is ", $self->job_title, "\n";
+      $self->SUPER::print_info();
+      print "Its title is ", $self->title, "\n";
   }
 
-The C<SUPER::> bit tells Perl to look for the C<print_greeting()> in
-the C<Employee> class's inheritance chain. When it finds the parent
-class that implements this method, the method is called.
+The C<SUPER::> bit tells Perl to look for the C<print_info()> in the
+C<File::MP3> class's inheritance chain. When it finds the parent class
+that implements this method, the method is called.
 
 We mentioned multiple inheritance earlier. The main problem with
 multiple inheritance is that it greatly complicates method resolution.
@@ -326,13 +339,12 @@ that its parent class uses. In reality, subclassing sometimes involves
 violating encapsulation, but a good API can minimize the need to do
 this.
 
-We mentioned earlier that most Perl objects are implemented as hash
-references 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 reference. 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
-reference directly.
+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.
 
 =head2 Composition
 
@@ -340,11 +352,11 @@ In object-oriented code, we often find that one object references
 another object. This is called B<composition>, or a B<has-a>
 relationship.
 
-Earlier, we mentioned that the C<Person> class's C<birth_date> accessor
-could return a L<DateTime> object. This is a perfect example of
-composition. We could go even further, and make objects for name and
-country as well. The C<Person> class would then be B<composed> of
-several other objects.
+Earlier, we mentioned that the C<File> class's C<last_mod_time>
+accessor could return a L<DateTime> object. This is a perfect example
+of composition. We could go even further, and make the C<path> and
+C<content> accessors return objects as well. The C<File> class would
+then be B<composed> of several other objects.
 
 =head2 Roles
 
@@ -382,50 +394,50 @@ the right fit for your problem:
 
 =over 4
 
-=item
+=item *
 
 The system being designed is large, or is likely to become large.
 
-=item
+=item *
 
 The data can be aggregated into obvious structures, especially if
 there's a large amount of data in each aggregate.
 
-=item
+=item *
 
 The various types of data aggregate form a natural hierarchy that
 facilitates the use of inheritance and polymorphism.
 
-=item
+=item *
 
 You have a piece of data on which many different operations are
 applied.
 
-=item
+=item *
 
 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.
 
-=item
+=item *
 
 It's likely you'll have to add new data types later.
 
-=item
+=item *
 
 The typical interactions between pieces of data are best represented by
 operators.
 
-=item
+=item *
 
 The implementation of individual components of the system is likely to
 change over time.
 
-=item
+=item *
 
 The system design is already object-oriented.
 
-=item
+=item *
 
 Large numbers of other programmers will be using your code modules.
 
@@ -456,6 +468,21 @@ is the Common Lisp Object System, but it also borrows ideas from
 Smalltalk and several other languages. C<Moose> was created by Stevan
 Little, and draws heavily from his work on the Perl 6 OO design.
 
+Here is our C<File> class using C<Moose>:
+
+  package File;
+  use Moose;
+
+  has path          => ( is => 'ro' );
+  has content       => ( is => 'ro' );
+  has last_mod_time => ( is => 'ro' );
+
+  sub print_info {
+      my $self = shift;
+
+      print "This file is at ", $self->path, "\n";
+  }
+
 C<Moose> provides a number of features:
 
 =over 4
@@ -468,26 +495,11 @@ your class works simpler and more palatable.  This lets you describe
 I<what> your class is, rather than having to tell Perl I<how> to
 implement your class.
 
-Here's a simple but complete C<Moose> class:
-
-  package Person;
-  use Moose;
-
-  has name         => ( is => 'ro' );
-  has birth_date   => ( is => 'ro' );
-  has country_code => ( is => 'ro' );
-
-  sub print_greeting {
-      my $self = shift;
-
-      print "Hello, ", $self->name, "\n";
-  }
-
 The C<has()> subroutine declares an attribute, and C<Moose>
 automatically creates accessors for these attributes. It also takes
 care of creating a C<new()> method for you. This constructor knows
 about the attributes you declared, so you can set them when creating a
-new C<Person>.
+new C<File>.
 
 =item * Roles built-in
 
@@ -522,7 +534,7 @@ invalid value, our code will throw an error.
 
 Perl's built-in introspection features are fairly minimal. C<Moose>
 builds on top of them and creates a full introspection layer for your
-classes. This lets you ask questions like "what methods does the Person
+classes. This lets you ask questions like "what methods does the File
 class implement?" It also lets you modify your classes
 programmatically.
 
@@ -570,27 +582,30 @@ compiler. If you need to install your software on a system without a
 compiler, or if having I<any> dependencies is a problem, then C<Moose>
 may not be right for you.
 
-=head3 Mouse
+=head3 Moo
 
 If you try C<Moose> and find that one of these issues is preventing you
-from using C<Moose>, we encourage you to consider L<Mouse> next.
-C<Mouse> implements a subset of C<Moose>'s functionality in a simpler
-package. For all features that it does implement, the end-user API is
-I<identical> to C<Moose>, meaning you can switch from C<Mouse> to
+from using C<Moose>, we encourage you to consider L<Moo> next. C<Moo>
+implements a subset of C<Moose>'s functionality in a simpler package.
+For most features that it does implement, the end-user API is
+I<identical> to C<Moose>, meaning you can switch from C<Moo> to
 C<Moose> quite easily.
 
-C<Mouse> does not implement most of C<Moose>'s introspection API, so
-it's often faster when loading your modules. Additionally, it has no
-I<required> non-core dependencies and can run without a compiler. If
-you do have a compiler, C<Mouse> will use it to compile some of its
-code for a speed boost.
+C<Moo> does not implement most of C<Moose>'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.
+
+One of C<Moo>'s most compelling features is its interoperability with
+C<Moose>. When someone tries to use C<Moose>'s introspection API on a
+C<Moo> class or role, it is transparently inflated into a C<Moose>
+class or role. This makes it easier to incorporate C<Moo>-using code
+into a C<Moose> code base and vice versa.
 
-Finally, it ships with a C<C<Mouse>::Tiny> module that takes most of
-C<Mouse>'s features and bundles them up in a single module file. You
-can copy this module file into your application's library directory for
-easy bundling.
+For example, a C<Moose> class can subclass a C<Moo> class using
+C<extends> or consume a C<Moo> role using C<with>.
 
-The C<Moose> authors hope that one day C<Mouse> can be made obsolete by
+The C<Moose> authors hope that one day C<Moo> can be made obsolete by
 improving C<Moose> enough, but for now it provides a worthwhile
 alternative to C<Moose>.
 
@@ -606,19 +621,19 @@ features it supports.
 Even though it doesn't do much, it is still preferable to writing your
 own classes from scratch.
 
-Here's our C<Person> class with C<Class::Accessor>:
+Here's our C<File> class with C<Class::Accessor>:
 
-  package Person;
+  package File;
   use Class::Accessor 'antlers';
 
-  has name         => ( is => 'ro' );
-  has birth_date   => ( is => 'ro' );
-  has country_code => ( is => 'ro' );
+  has path          => ( is => 'ro' );
+  has content       => ( is => 'ro' );
+  has last_mod_time => ( is => 'ro' );
 
-  sub print_greeting {
+  sub print_info {
       my $self = shift;
 
-      print "Hello, ", $self->name, "\n";
+      print "This file is at ", $self->path, "\n";
   }
 
 The C<antlers> import flag tells C<Class::Accessor> that you want to
@@ -638,15 +653,15 @@ name. It has an incredibly minimal API and absolutely no dependencies
 (core or not). Still, we think it's a lot easier to use than writing
 your own OO code from scratch.
 
-Here's our C<Person> class once more:
+Here's our C<File> class once more:
 
-  package Person;
-  use Object::Tiny qw( name birth_date country_code );
+  package File;
+  use Object::Tiny qw( path content last_mod_time );
 
-  sub print_greeting {
+  sub print_info {
       my $self = shift;
 
-      print "Hello, ", $self->name, "\n";
+      print "This file is at ", $self->path, "\n";
   }
 
 That's it!
@@ -677,8 +692,8 @@ Here's a brief recap of the options we covered:
 =item * L<Moose>
 
 C<Moose> is the maximal option. It has a lot of features, a big
-ecosystem, and a thriving user base. We also covered L<Mouse> briefly.
-C<Mouse> is C<Moose> lite, and a reasonable alternative when Moose
+ecosystem, and a thriving user base. We also covered L<Moo> briefly.
+C<Moo> is C<Moose> lite, and a reasonable alternative when Moose
 doesn't work for your application.
 
 =item * L<Class::Accessor>
@@ -717,10 +732,10 @@ built-in OO works.
 
 =head1 CONCLUSION
 
-As we said before, Perl's minimal OO system has lead to a flourishing
-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 in
-2011.
+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.
 
 For small systems, L<Object::Tiny> and L<Class::Accessor> both provide
 minimal object systems that take care of basic boilerplate for you.