- uploaded *correct* versions of HashRef/ArrayRef/Perl 5 OO vs. Moose OO pods
[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         } else {
53             die "ERROR: can't create object without 'script_name' ";
54         } # if ( exists $args{script_name} )
55
56         # return the object reference back to the caller
57         return $self;
58     } # sub new
59     
60     sub script_name {
61         my $self = shift;
62         # check for arguments; use the argument if passed in, otherwise 
63         # return the existing value (if any)
64         if (@_) { $self->{script_name} = shift }
65         return $self->{script_name};
66     } # sub script_name
67
68     package main;
69     use strict;
70     use warnings;
71
72     my $demo = Perl5::Demo->new( script_name => $0 );
73
74     print "My name is " . $demo->script_name . "\n";
75     print "I am a " . ref($demo) . " type of object\n";
76
77 Looks more complex, right?  Moose does a lot of the labor when working with
78 Perl objects, so that you don't have to.  What are some of the specific
79 differences between Moose and Perl 5 Objects?
80
81 =head3 Difference #1 - declaration of object attributes
82
83 Both the Moose and Perl 5 objects have one attribute, C<script_name>.  It's a
84 good programming practice to always validate user input, so we have the Perl 5
85 object check to make sure that the user passes in the C<script_name> attribute
86 to it when the object is created.  The Moose object automatically checks this
87 for us when we set C<required =E<gt> 1> in the C<has> function for the Moose
88 object.
89
90 In more advanced Moose usage, you can use something called 'type constraints'
91 when creating your Moose objects.  Type constraints are used to validate what
92 the user passes in when setting Moose object attributes.  If the user passes
93 in a type of data that Moose is not expecting, then the type constraints in
94 Moose (specifically, the L<Moose::Util::TypeConstraint> module) will let the
95 user know this in no uncertain terms.  Type constraints in Moose can be as
96 simple as strings or numbers, or as complex as other Moose objects.
97
98 =head3 Difference #2 - strict and warning pragmas
99
100 Moose sets the 'strict' and 'warnings' pragmas for you automatically.  We have
101 to do this for ourselves in the Perl 5 example.
102
103 =head3 Difference #3 - Determining an object's class name
104
105 The C<ref()> function in Perl 5 is how you determine an object's class name.
106 The proper way to do this with Moose is C<$object-E<gt>meta-E<gt>name>;
107     
108     # an object's class name in Perl 5 OO
109     print "I am a " . ref($demo) . " type of object\n";
110
111     # an object's class name in Moose
112     print "I am a " . $demo->meta->name . " type of object\n";
113
114 =head3 Difference #4 - Assigning values to Moose object attributes
115
116 When you wish to assign a value directly to an object attribute for a Perl 5
117 object, you can either create an object method that handles the value for you;
118
119     package Perl5Object;
120     sub set_x { # some code here that sets 'x' }
121     package main;
122     # later on...
123     $self->set_x(0);
124
125 or you can assign the value directly to the Perl 5 object attribute like this:
126
127     $self->{x} = 0; 
128
129 Moose creates object methods for handling attributes for you, as long as you
130 specified C<is =E<gt> rw> for each C<has> statement inside the object
131 declaration.  This is mentioned in L<Moose::Cookbook::WTF>, in the section
132 labeld B<Accessors>, but briefly:
133
134     package MooseObject;
135     has 'x' => (is => 'rw');
136     package main; 
137     # later on...
138     $self->x(0);    
139
140 The syntax shown for the Perl 5 object (C<$self-E<gt>{x} = 0>) will also work
141 on the Moose object, as Moose objects are blessed hashes just like the average
142 Perl object is.  However, if you access the object's hash reference directly
143 via the latter syntax:
144
145 1) Moose will no longer be to enforce having that attribute be read-only if
146 you used (C<is =E<gt> ro>) in the object's declaration.
147
148 2) You break that object's encapsulation, which is one of the reasons you want
149 to use objects in the first place, right?
150
151 =head1 SEE ALSO
152
153 =over 4
154
155 =item L<Moose::Cookbook::Recipe1> - The 'Point' object example
156
157 =item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
158
159 =item L<Moose::Cookbook::WTF> - For when things go wrong with Moose
160
161 =back
162
163 =head1 AUTHOR
164
165 Brian Manning <elspicyjack at gmail dot com>
166
167 =head1 COPYRIGHT AND LICENSE
168
169 Copyright (c)2008 by Infinity Interactive, Inc., Brian Manning
170
171 This documentation is free software; you can redistribute it and/or modify
172 it under the same terms as Perl itself.
173
174 =cut