diff options
Diffstat (limited to 'upstream/debian-bookworm/man1/perlobj.1')
-rw-r--r-- | upstream/debian-bookworm/man1/perlobj.1 | 1219 |
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. |