- changed snack description to better describe how Moose works
[gitmo/Moose.git] / lib / Moose / Cookbook / Snack / Perl5ObjsVsMooseObjs.pod
1
2 =pod
3
4 =head1 NAME
5
6 Moose::Cookbook::Snack::Perl5ObjsVsMooseObjs - Short comparison between Perl 5
7 objects and Moose objects
8
9 =head1 SYNOPSIS
10
11     package Moose::Demo;
12     use Moose; # automagically sets 'strict' and 'warnings'
13
14     has 'script_name' => ( is => 'rw', required => 1);
15
16     package main;
17     
18     # '$0' is the name of this script, set automatically by Perl
19     my $demo = Moose::Demo->new( script_name => $0 );
20
21     print "My name is " . $demo->script_name . "\n";
22     print "I am a " . $demo->meta->name . " type of object\n";
23
24 =head1 DESCRIPTION
25
26 So what's the big stink about Moose?  Perl 5 comes with objects and object
27 oriented programming already.  Given the above Moose code, what would similar
28 code look like in the existing Perl 5 object-oriented style of programming?
29 Let's take a look and find out...
30
31 =head2 Perl 5 OO Example
32
33     # Perl 5 Object, as taught by the 'perltoot' POD page
34     package Perl5::Demo;
35     use strict;
36     use warnings;
37
38     
39     sub new {
40         my $class = shift;
41         # assign the rest of the method arguments to a temp hash
42         my %args = @_;
43
44         # create the object out of a blessed hash reference
45         my $self = bless ( {}, ref($class) || $class );
46         # create the script_name attribute
47         $self->{script_name} = undef;
48
49         # verify that the user passed in the 'script_name' attribute
50         if ( exists $args{script_name} ) {
51             $self->script_name($args{script_name});
52         } 
53         else {
54             die "ERROR: can't create object without 'script_name' ";
55         }
56
57         # return the object reference back to the caller
58         return $self;
59     }
60     
61     sub script_name {
62         my $self = shift;
63         # check for arguments; use the argument 
64         # if passed in, otherwise return the 
65         # existing value (if any)
66         if (@_) { 
67             $self->{script_name} = shift;
68         }
69         return $self->{script_name};
70     }
71
72     package main;
73     use strict;
74     use warnings;
75
76     my $demo = Perl5::Demo->new( script_name => $0 );
77
78     print "My name is " . $demo->script_name . "\n";
79     print "I am a " . ref($demo) . " type of object\n";
80
81 Looks more complex, right?  Moose does a lot of the labor when working with
82 Perl objects, so that you don't have to.  What are some of the specific
83 differences between Moose and Perl 5 Objects?
84
85 =head3 Difference #1 - declaration of object attributes
86
87 Both the Moose and Perl 5 objects have one attribute, C<script_name>.  It's a
88 good programming practice to always validate user input, so we have the Perl 5
89 object check to make sure that the user passes in the C<script_name> attribute
90 to it when the object is created.  The Moose object automatically checks this
91 for us when we set C<required =E<gt> 1> in the C<has> function for the Moose
92 object.
93
94 In more advanced Moose usage, you can use something called 'type constraints'
95 when creating your Moose objects.  Type constraints are used to validate what
96 the user passes in when setting Moose object attributes.  If the user passes
97 in a type of data that Moose is not expecting, then the type constraints in
98 Moose (specifically, the L<Moose::Util::TypeConstraint> module) will let the
99 user know this in no uncertain terms.  Type constraints in Moose can be as
100 simple as strings or numbers, or as complex as other Moose objects.
101
102 =head3 Difference #2 - strict and warning pragmas
103
104 Moose sets the 'strict' and 'warnings' pragmas for you automatically.  We have
105 to do this for ourselves in the Perl 5 example.
106
107 =head3 Difference #3 - Determining an object's class name
108
109 The C<ref()> function in Perl 5 is how you determine an object's class name.
110 The proper way to do this with Moose is C<$object-E<gt>meta-E<gt>name>;
111     
112     # an object's class name in Perl 5 OO
113     print "I am a " . ref($demo) . " type of object\n";
114
115     # an object's class name in Moose
116     print "I am a " . $demo->meta->name . " type of object\n";
117
118 Moose builds on C<Class::MOP> to provide a rich introspection API that
119 goes way beyond just getting the class name. Check out the
120 C<Class::MOP> documentation for more details.
121
122 =head3 Difference #4 - Assigning values to Moose object attributes
123
124 When you wish to assign a value directly to an object attribute for a Perl 5
125 object, you can either create an object method that handles the value for you;
126
127     package Perl5Object;
128     sub set_x { # some code here that sets 'x' }
129     package main;
130     # later on...
131     $self->set_x(0);
132
133 or you can assign the value directly to the Perl 5 object attribute like this:
134
135     $self->{x} = 0; 
136
137 Moose creates object methods for handling attributes for you, as long as you
138 specified C<is =E<gt> rw> for each C<has> statement inside the object
139 declaration.  This is mentioned in L<Moose::Cookbook::WTF>, in the section
140 labeld B<Accessors>, but briefly:
141
142     package MooseObject;
143     has 'x' => (is => 'rw');
144     package main; 
145     # later on...
146     $self->x(0);    
147
148 The syntax shown for the Perl 5 object (C<$self-E<gt>{x} = 0>) will
149 also work on the Moose object, as Moose objects are, by default,
150 blessed hashes just like the average Perl object is.  However, if you
151 access the object's hash reference directly via the latter syntax you
152 will have several problems.
153
154 First, Moose will no longer be able to enforce attribute constraints,
155 such as read-only or type constraints. Second, you've broken that
156 object's encapsulation, and encapsulation is one of the reasons you
157 want to use objects in the first place, right?
158
159 =head1 SEE ALSO
160
161 =over 4
162
163 =item L<Moose::Cookbook::Recipe1> - The 'Point' object example
164
165 =item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
166 and the tools to extend them or create your own.
167
168 =item L<Moose::Cookbook::WTF> - For when things go wrong with Moose
169
170 =back
171
172 =head1 AUTHOR
173
174 Brian Manning <elspicyjack at gmail dot com>
175
176 =head1 COPYRIGHT AND LICENSE
177
178 Copyright 2006-2008 by Infinity Interactive, Inc.
179
180 L<http://www.iinteractive.com>
181
182 This library is free software; you can redistribute it and/or modify
183 it under the same terms as Perl itself.
184
185 =cut