excluded blib
[urisagit/Stem.git] / Cookbook / World3.pm
CommitLineData
4536f655 1package World3 ;
2
3use strict;
4
5# This is the specification table that describes the attributes for
6# this object. The only attribute is the name of the planet and it
7# defaults to 'X'
8
9my $attr_spec =
10[
11 {
12 'name' => 'planet',
13 'default' => 'X',
14 },
15];
16
17# The new method constructs the object which is returned to the
18# configuration system where it will be registered.
19
20sub new {
21
22 my( $class ) = shift ;
23
24# The call to parse_args takes the attribute specification and the
25# configuration arguments and creates a cell object
26
27 my $self = Stem::Class::parse_args( $attr_spec, @_ ) ;
28
29 return ( $self );
30}
31
32# This command method is similar to the one in World1 except we
33# we use the object argument and return the name from that object.
34
35sub hello_cmd {
36
37 my( $self ) = @_;
38
39 return "Hello world from $self->{'planet'}!\n";
40}
41
42=head1 Stem Cookbook - World3
43
44=head1 NAME
45
46World2 - A simple object level B<Stem> cell.
47
48=head1 DESCRIPTION
49
50This cell is an extension of the B<World1> cell. In this example,
51instead of a single class cell with a fixed response value, we now can
52create multiple cells (registered objects) each with their own private
53data. The world_cmd method will return the planet's name stored in the
54cell.
55
56=head1 CREATING THE CELL
57
58This cell illustrates the basic way to construct objects in Stem.
59
60=over 4
61
62=item *
63
64A specification table is required to describe the allowed attributes
65of the object. This is a list of hashes with each hash describing one
66attribute. It is usually defined in a file lexical variable commonly
67named $attr_spec which is assigned an anonymous list of attribute
68descriptions. The fields that describe the attributes are defined in
69the F<Stem::Class> module.
70
71=item *
72
73An object constructor is called and is passed a list of key value
74arguments. This class method can be called via a configuration (which
75uses default name of 'new') or from any Stem code. The constructor
76passes its attribute specification table and the passed arguments to
77the Stem::Class::parse_args routine which returns the new object The
78constructor method checks if an error happened by seeing if that
79returned value is an object (ref is true) or else it must be an error
80string. Any error string is returned to the caller of this
81constructor. This is the standard way Stem handles errors, references
82are good values and scalars (error strings) are bad. This propogation
83of error strings up the call stack is consistantly used in all Stem
84modules. After a successful construction of an object, the constructor
85method can do additional work and then it returns the object. The
86caller of the constructor will also check for an object or error
87string. The common case of a configuration file constructing a Stem
88object cell with register a good cell or print the error string and
89die.
90
91=back
92
93=head2 ATTRIBUTE SPECIFICATION
94
95Object cells require an attribute specification that describes
96the information we want to exist independently in each object
97cell when it is created. The following is the attribute specification
98used in C<World2>:
99
100$attr_spec =
101[
102 {
103 'name' => 'planet',
104 'default' => 'X',
105
106 },
107
108];
109
110This specification indicates that this cell has an attribute
111named I<planet>. It will default to the value of I<X> if
112this attribute is not specified in the configuration arguments
113for this cell. Some of the attribute specification tags are I<name>,
114I<type>, I<default>, I<required>, I<class>, and I<help>. For more
115information on cell configuration please see
116B<Stem Object and Cell Creation and Configuration Design Notes> and
117B<Stem Cell Design Notes>.
118
119=head2 OBJECT CONSTRUCTOR
120
121This is a minimal B<Stem> constructor with the usual name I<new>. you
122can invoke any other method as a constructor from a configuration by
123using the 'method' field:
124
125sub new {
126
127 my ( $class ) = shift;
128
129 my $self = Stem::Class::parse_args( $attr_spec, @_ );
130 return $self unless ref $self ;
131
132 return ( $self );
133
134}
135
136To create a B<Stem> object cell we call the C<Stem::Class::parse_args>
137routine and pass it the object cell attribute specification and the
138rest of the arguments passed into this constructor. The rest of the
139arguments come from the I<args> field in the configuration for this cell.
140The parse_args function then returns the newly created object to the
141caller, which is usually the configuration system but it could be any
142other code as well. An important observation to make here is the
143B<Stem> error handling technique. Errors, in B<Stem>, are propagated
144up the call stack bu returning an error string rather than a
145reference. This is the typical Stem way of determining whether of not
146an error condition had occurred. Constructors or subroutines which
147normally return objects or references will return a string value as
148an error message. This is always checked by the caller and will usually
149be passed up the call stack until a top level subroutine handles it.
150
151=head1 CREATING THE CONFIGURATION FILE
152
153The following B<Stem> configuration file is used to bring a
154World2 object level cell into existance in the B<Stem> environment.
155
156[
157 class => 'Console',
158],
159
160[
161 class => 'World2',
162 name => 'first_planet',
163 args => [],
164
165],
166
167[
168 class => 'World2',
169 name => 'second_planet',
170 args => [
171 planet => 'venus',
172
173 ],
174
175],
176
177
178As explained in F<World1.pm>, we create a
179C<Stem::Console> cell to allow for the creation of a Stem console
180to manually send command messages and display their responses.
181We also create two object level C<World2> cells.
182The first, we name I<first_planet> and it defaults to having its planet
183attribute set to 'first_planet'. The second, we name I<second_planet> and set its
184planet attribute to 'venus'.
185
186Using the I<args> specifier in the cell configuration indicates
187that we are creating an I<object> cell rather than a class cell.
188It indicates to the B<Stem> cell creation environment that we
189wish to execute the constructor of the specified class to
190create an object of the class rather than using the B<Stem>
191module as a class itself. Using object cells allow us to instantiate
192multiple objects with unique values, addressed and subsequent
193behavior.
194
195=head1 USAGE
196
197Execute C<run_stem world2> from the command line to run this
198configuration. You will be greeted with the B<StemE<gt>> prompt.
199It is now possible to send a message manually into the system.
200
201Type the following at the B<Stem> prompt:
202
203B<reg status>
204
205This will show the status of the local B<Stem> hub. You
206will notice the two entries for the object cells created
207by the configuration file under the object cell section.
208
209Now execute the same command as you did in F<World1>:
210
211B<first_planet hello>
212
213B<Hello, World! (from X)>
214
215B<second_planet hello>
216
217B<Hello, World! (from venus)>
218
219As in F<World1>, the above triggers the C<hello_cmd> method. However,
220now we are triggering the C<hello_cmd> method on separate object cells
221rather than a single class cell.
222
223
224=head1 SEE ALSO
225
226F<Stem Cookbook Part 1>
227
228F<Stem Cookbook Part 3>
229
230F<World2 Module>
231
232=cut
233
234
2351;