-
-
07 Nov 2021 03:41:58 UTC
- Distribution: Moose
- Source (raw)
- Browse (raw)
- Changes
- Homepage
- How to Contribute
- Repository
- Issues (71)
- Testers (2647 / 3 / 1)
- Kwalitee
Bus factor: 3- 92.11% Coverage
- License: perl_5
- Perl: v5.8.3
- Activity
24 month- Tools
- Download (881.54KB)
- MetaCPAN Explorer
- Permissions
- Subscribe to distribution
- Permalinks
- This version
- Latest version
and 142 contributors-
Stevan Little
-
Dave Rolsky
-
Jesse Luehrs
-
Shawn M Moore
-
יובל קוג'מן (Yuval Kogman)
-
Florian Ragwitz
-
Hans Dieter Pearcey
-
Chris Prather
-
Matt S Trout
-
Upasana Shukla
-
Graham Knop
-
Tomas Doran
-
Ricardo Signes
-
Guillermo Roditi
-
John Napiorkowski
-
Aankhen
-
Todd Hepler
-
Jonathan Rockway
-
Gerda Shank
-
Perlover
-
Shlomi Fish
-
Brad Bowman
-
Justin Hunter
-
Kent Fredric
-
Paul Driver
-
Anders Nor Berle
-
Brian Manning
-
gfx
-
Jay Hannah
-
Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯
-
Leon Brocard
-
Olivier Mengué
-
Rafael Kitover
-
Christian Hansen
-
Cory Watson
-
Dagfinn Ilmari Mannsåker
-
Paul Jamieson Fenwick
-
Robert Buels
-
Dan Dascalescu
-
Marcel Grünauer
-
Scott McWhirter
-
Ævar Arnfjörð Bjarmason
-
Daisuke Maki (lestrrat)
-
Dylan William Hardison
-
Patrick Donelan
-
Stefan O'Rear
-
Tokuhiro Matsuno
-
Ash Berlin
-
Chris Weyl
-
Eric Wilhelm
-
Jess Robinson
-
Marc Mims
-
Marcus Ramberg
-
Mark Allen
-
Mateu X Hunter
-
matthof
-
Robert 'phaylon' Sedlacek
-
Zachary Lome
-
Aran Clary Deltac
-
Chip
-
Christopher J. Madsen
-
Curtis Jewell
-
Evan Carroll
-
Mark A. Stratman
-
Mark Fowler
-
Matthew Horsfall
-
mauke
-
Michael LaGrasta
-
Michael Rykov
-
Mike Whitaker
-
Moritz Onken
-
Nelo Onyiah
-
Nick Perez
-
Robert Boone
-
Robin V
-
rodrigolive
-
shelling
-
Thomas Sibley
-
Tom Hukins
-
Wallace Reis
-
Aaron Cohen
-
Adam J. Foxson
-
Adam Kennedy
-
Andy Jack
-
Anirvan Chatterjee
-
Ansgar Burchardt
-
A. Sinan Unur
-
Ben Hutton
-
Brendan Byrd
-
Chad Granum
-
Chankey Pathak
-
Chia-liang Kao
-
Christian Walde (Mithaldu)
-
chromatic
-
Dann
-
Dave Romano
-
David Leadbeater
-
David Steinbrunner
-
dmaestro
-
E. Choroba
-
franck cuny
-
Frew Schmidt
-
gregor herrmann
-
hakim
-
Henry Van Styn
-
James Marca
-
Jason May
-
Jay Allen
-
Jay Kuri
-
Jeff Bisbee
-
Jens Berthold
-
Jesse Vincent
-
joel
-
John Douglas Porter
-
John Goulah
-
Justin DeVuyst
-
Kang-min Liu
-
Leon Timmermans
-
Mark O Grady
-
Matt Kraai
-
Michael Schout
-
Nathan Gray
-
Olaf Alders
-
Olof Johansson
-
Paul Cochrane
-
Paweł Murias
-
Pedro Melo
-
Peter Shangov
-
Philippe Bruhat (BooK)
-
Philipp Gortan
-
Phillip Smith
-
Piotr Roszatycki
-
pktm
-
rouzier
-
Sam Vilain
-
sherrardb
-
Simon Reinhardt
-
sue spence
-
Tuomas Jormola
-
wickline
-
Yanick Champoux
-
Zoffix Znet
- Dependencies
- Carp
- Class::Load
- Class::Load::XS
- Data::OptList
- Devel::GlobalDestruction
- Devel::OverloadInfo
- Devel::StackTrace
- Dist::CheckConflicts
- Eval::Closure
- List::Util
- MRO::Compat
- Module::Runtime
- Module::Runtime::Conflicts
- Package::DeprecationManager
- Package::Stash
- Package::Stash::XS
- Params::Util
- Scalar::Util
- Sub::Exporter
- Sub::Util
- Try::Tiny
- parent
- strict
- warnings
- Reverse dependencies
- CPAN Testers List
- Dependency graph
NAME
Moose::Cookbook::Basics::Point_AttributesAndSubclassing - Point and Point3D classes, showing basic attributes and subclassing.
VERSION
version 2.2201
SYNOPSIS
package Point; use Moose; has 'x' => (isa => 'Int', is => 'rw', required => 1); has 'y' => (isa => 'Int', is => 'rw', required => 1); sub clear { my $self = shift; $self->x(0); $self->y(0); } package Point3D; use Moose; extends 'Point'; has 'z' => (isa => 'Int', is => 'rw', required => 1); after 'clear' => sub { my $self = shift; $self->z(0); }; package main; # hash or hashrefs are ok for the constructor my $point1 = Point->new(x => 5, y => 7); my $point2 = Point->new({x => 5, y => 7}); my $point3d = Point3D->new(x => 5, y => 42, z => -5);
DESCRIPTION
This is the classic Point example. It is taken directly from the Perl 6 Apocalypse 12 document, and is similar to the example found in the classic K&R C book as well.
As with all Perl 5 classes, a Moose class is defined in a package. Moose handles turning on
strict
andwarnings
for us, so all we need to do is sayuse Moose
, and no kittens will die.When Moose is loaded, it exports a set of sugar functions into our package. This means that we import some functions which serve as Moose "keywords". These aren't real language keywords, they're just Perl functions exported into our package.
Moose automatically makes our package a subclass of Moose::Object. The Moose::Object class provides us with a constructor that respects our attributes, as well other features. See Moose::Object for details.
Now, onto the keywords. The first one we see here is
has
, which defines an instance attribute in our class:has 'x' => (isa => 'Int', is => 'rw', required => 1);
This will create an attribute named
x
. Theisa
parameter says that we expect the value stored in this attribute to pass the type constraint forInt
(1). The accessor generated for this attribute will be read-write.The
required => 1
parameter means that this attribute must be provided when a new object is created. A point object without coordinates doesn't make much sense, so we don't allow it.We have defined our attributes; next we define our methods. In Moose, as with regular Perl 5 OO, a method is just a subroutine defined within the package:
sub clear { my $self = shift; $self->x(0); $self->y(0); }
That concludes the Point class.
Next we have a subclass of Point, Point3D. To declare our superclass, we use the Moose keyword
extends
:extends 'Point';
The
extends
keyword works much likeuse base
/use parent
. First, it will attempt to load your class if needed. However, unlikebase
, theextends
keyword will overwrite any previous values in your package's@ISA
, whereuse base
willpush
values onto the package's@ISA
.It is my opinion that the behavior of
extends
is more intuitive. (2).Next we create a new attribute for Point3D called
z
.has 'z' => (isa => 'Int', is => 'rw', required => 1);
This attribute is just like Point's
x
andy
attributes.The
after
keyword demonstrates a Moose feature called "method modifiers" (or "advice" for the AOP inclined):after 'clear' => sub { my $self = shift; $self->z(0); };
When
clear
is called on a Point3D object, our modifier method gets called as well. Unsurprisingly, the modifier is called after the real method.In this case, the real
clear
method is inherited from Point. Our modifier method receives the same arguments as those passed to the modified method (just$self
here).Of course, using the
after
modifier is not the only way to accomplish this. This is Perl, right? You can get the same results with this code:sub clear { my $self = shift; $self->SUPER::clear(); $self->z(0); }
You could also use another Moose method modifier,
override
:override 'clear' => sub { my $self = shift; super(); $self->z(0); };
The
override
modifier allows you to use thesuper
keyword to dispatch to the superclass's method in a very Ruby-ish style.The choice of whether to use a method modifier, and which one to use, is often a question of style as much as functionality.
Since Point inherits from Moose::Object, it will also inherit the default Moose::Object constructor:
my $point1 = Point->new(x => 5, y => 7); my $point2 = Point->new({x => 5, y => 7}); my $point3d = Point3D->new(x => 5, y => 42, z => -5);
The
new
constructor accepts a named argument pair for each attribute defined by the class, which you can provide as a hash or hash reference. In this particular example, the attributes are required, and callingnew
without them will throw an error.my $point = Point->new( x => 5 ); # no y, kaboom!
From here on, we can use
$point
and$point3d
just as you would any other Perl 5 object. For a more detailed example of what can be done, you can refer to the t/recipes/basics_point_attributesandsubclassing.t test file.Moose Objects are Just Hashrefs
While this all may appear rather magical, it's important to realize that Moose objects are just hash references under the hood (3). For example, you could pass
$self
toData::Dumper
and you'd get exactly what you'd expect.You could even poke around inside the object's data structure, but that is strongly discouraged.
The fact that Moose objects are hashrefs means it is easy to use Moose to extend non-Moose classes, as long as they too are hash references. If you want to extend a non-hashref class, check out
MooseX::InsideOut
.CONCLUSION
This recipe demonstrates some basic Moose concepts, attributes, subclassing, and a simple method modifier.
FOOTNOTES
- (1)
-
Moose provides a number of builtin type constraints, of which
Int
is one. For more information on the type constraint system, see Moose::Util::TypeConstraints. - (2)
-
The
extends
keyword supports multiple inheritance. Simply pass all of your superclasses toextends
as a list:extends 'Foo', 'Bar', 'Baz';
- (3)
-
Moose supports using instance structures other than blessed hash references (such as glob references - see MooseX::GlobRef).
SEE ALSO
- Method Modifiers
-
The concept of method modifiers is directly ripped off from CLOS. A great explanation of them can be found by following this link.
http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html
AUTHORS
Stevan Little <stevan@cpan.org>
Dave Rolsky <autarch@urth.org>
Jesse Luehrs <doy@cpan.org>
Shawn M Moore <sartak@cpan.org>
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
Karen Etheridge <ether@cpan.org>
Florian Ragwitz <rafl@debian.org>
Hans Dieter Pearcey <hdp@cpan.org>
Chris Prather <chris@prather.org>
Matt S Trout <mstrout@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2006 by Infinity Interactive, Inc.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
Module Install Instructions
To install Moose, copy and paste the appropriate command in to your terminal.
cpanm Moose
perl -MCPAN -e shell install Moose
For more information on module installation, please visit the detailed CPAN module installation guide.