cleaned up some debug prints
[urisagit/Stem.git] / Cookbook / World4.pm
CommitLineData
4536f655 1package World4 ;
2
3use strict;
4
5my $attr_spec =
6[
7 {
8 'name' => 'planet',
9 'default' => 'uranus',
10 },
11];
12
13sub new {
14
15 my( $class ) = shift ;
16 my $self = Stem::Class::parse_args( $attr_spec, @_ ) ;
17
18 return ( $self );
19}
20
21# based on who was the receiver of the message
22# we return with the appropriate response
23
24sub hello_cmd {
25
26 my( $self ) = @_;
27
28 return "Hello world from $self->{'planet'}!\n";
29}
30
31sub name_cmd {
32
33 my ( $self, $msg ) = @_ ;
34
35 my $data = $msg->data() ;
36
37 return unless $data ;
38
39 $self->{'planet'} = ${$data} ;
40
41 return ;
42}
43
44
45
46
47=head1 Stem Cookbook - World3
48
49=head1 NAME
50
51World3 - Mixing class and object B<Stem> cells.
52
53=head1 DESCRIPTION
54
55This is an extension of the B<Stem Cookbook Part 1 & Stem Cookbook Part 2> where
56we talked about the creation of B<Stem> class and object cells. In
57this example, we take the idea of a class cell and an object cell
58and combine them into a single B<Stem> module. We then have
59the ability of creating multiple cells (registered objects)
60with their own private data and at the same time have a
61class cell to manage a global resource.
62
63=head1 CREATING THE CELL
64
65The following lists the requirements for creating a B<Stem>
66object level cell:
67
68=over 4
69
70=item *
71
72An attribute specification
73
74=item *
75
76An object constructor
77
78=item *
79
80A class registration
81
82=back
83
84=head2 CHANGES FROM PART 1 AND PART 2
85
86Most of the code from Part 2 and Part 1 remain the same. We keep
87the same attribute specification as well as the same object cell
88constructor (except for a slight modification, see below).
89You remember from Part 1 that we created a class level
90B<Stem> cell from the configuration file,
91
92[
93 class => 'World1',
94 name => 'solar_system',
95
96]
97
98Because we do not have an args field, it means we are creating a
99class cell. In this example, we want a class cell to be created
100as a global resource only if an object cell is created. If the
101class cell is supposed to manage global information for object
102cells there is no need to create one if an object cell does not
103exist. To get this type of behavior, we register the class cell
104from within the B<Stem> module rather than from the configuration
105file,
106
107 Stem::Route::register_class( __PACKAGE__, 'solar_system' );
108
109This line (World3.pm, line 5) effectively registers the class cell
110with the B<Stem> message routing system using the package name
111and a name we wish to register the cell as.
112
113We keep referring to the class cell as a global resource, so in
114this example we create a global resource that the class cell will
115manage,
116
117 my @objects = ();
118
119On line 16 in World3.pm we create an array named objects that will
120be used to hold a reference to each of the World3 cell objects that are
121created from the configuration file (Note that this is not a
122requirement for creating this module and is just used as an example.
123It could have just as easily been a simple scalar, a hash, some
124other kind of object, or even nothing!).
125
126In order to populate this array of the objects that are created from
127the configuration file, we simply add them to the array when they
128are created in the object cell constructor,
129
130 push @objects, $self;
131
132This simply pushes the reference to the newely created World3 object cell
133onto the objects array. The class cell can now be used to represent the
134World3 object cells as a group.
135
136The next modification exists in the hello_cmd subroutine. We need a way
137to distiguish whether or not a message is being sent to an object cell
138as opposed to a class cell. As you might recall, the perl I<ref> function
139is used to determine if a scalar refers to a reference or a normal
140scalar value. If a subroutine is invoked from an object, the first
141argument of the subroutine will be a reference to the object itself,
142otherwise, it will be the string name of the class from which the subroutine
143belongs. The following code demonstrates a new hello_cmd subroutine
144that makes this distinction and performs accordingly,
145
146sub hello_cmd {
147
148 my ($class) = @_;
149
150 return "Hello world from $class->{'planet'}\n" if ref $class;
151
152 my $response_string = '';
153 foreach my $obj (@objects) {
154
155 $response_string .= "Hello world from $obj->{'planet'}\n";
156 }
157
158 return $response_string;
159}
160
161As you can see, we return the familiar "Hello world from $class->{'planet'}"
162string, but this time we check to make sure $class is a reference before
163returning the string. If it is not, we know that the hello_cmd was invoked
164from a message that was intended for the class cell. If this is the case, we
165concatenate a "Hello, World ..." string for each of the Hello3 object cells
166that were stored in the objects array and send that string as a response
167message to the sender.
168
169=head1 SEE ALSO
170
171F<Stem Cookbook Part 1>
172
173F<Stem Cookbook Part 2>
174
175F<Hello3 Module>
176
177=cut
178
1791;