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