@@ -7,6 +7,7 @@ It showcases custom constructors, private and public attributes, methods
7
7
and various aspects of signatures. It's not very much code, and yet the
8
8
result is interesting and, at times, useful.
9
9
10
+ = begin code
10
11
class Task {
11
12
has &!callback;
12
13
has Task @!dependencies;
@@ -41,27 +42,28 @@ result is interesting and, at times, useful.
41
42
);
42
43
43
44
$eat.perform();
45
+ = end code
44
46
45
47
= head1 Starting with class
46
48
47
- X < class >
48
- X < classes >
49
+ X < | class>
50
+ X < | classes>
49
51
50
- X < state >
51
- X < has >
52
- X < classes, has >
53
- X < behavior >
54
- X < classes, behavior >
52
+ X < | state>
53
+ X < | has>
54
+ X < | classes, has>
55
+ X < | behavior>
56
+ X < | classes, behavior>
55
57
56
58
Perl 6, like many other languages, uses the C < class > keyword to introduce a new
57
59
class. The block that follows may contain arbitrary code, just as with
58
60
any other block, but classes commonly contain state and behavior declarations.
59
61
The example code includes attributes (state), introduced through the C < has >
60
62
keyword, and behaviors introduced through the C < method > keyword.
61
63
62
- X < type object >
63
- X < defined >
64
- X < .defined >
64
+ X < | type object>
65
+ X < | defined>
66
+ X < | .defined>
65
67
66
68
Declaring a class creates a I < type object > which, by default, is
67
69
installed into the current package (just like a variable declared with
@@ -85,11 +87,11 @@ given object is a type object or not:
85
87
86
88
= head1 I can haz state?
87
89
88
- X < attributes >
89
- X < classes, attributes >
90
+ X < | attributes>
91
+ X < | classes, attributes>
90
92
91
- X < encapsulation >
92
- X < classes, encapsulation >
93
+ X < | encapsulation>
94
+ X < | classes, encapsulation>
93
95
94
96
The first three lines inside the class block all declare attributes (called
95
97
I < fields > or I < instance storage > in other languages). These are storage
@@ -103,9 +105,9 @@ code to invoke in order to perform the task that an object represents:
103
105
104
106
has &!callback;
105
107
106
- X < sigils, & >
107
- X < twigils >
108
- X < twigils, ! >
108
+ X < | sigils, &>
109
+ X < | twigils>
110
+ X < | twigils, !>
109
111
110
112
The C < & > sigil indicates that this attribute represents something invocable.
111
113
The C < ! > character is a I < twigil > , or secondary sigil. A twigil forms part of
@@ -126,10 +128,10 @@ The third attribute represents the state of completion of a task:
126
128
127
129
has Bool $.done;
128
130
129
- X < twigils, . >
130
- X < twigils, accessors >
131
- X < accessor methods >
132
- X < classes, accessors >
131
+ X < | twigils, .>
132
+ X < | twigils, accessors>
133
+ X < | accessor methods>
134
+ X < | classes, accessors>
133
135
134
136
This scalar attribute (with the C < $ > sigil) has a type of C < Bool > . Instead of
135
137
the C < ! > twigil, this twigil is C < . > . While Perl 6 does enforce encapsulation
@@ -153,15 +155,15 @@ change the attribute declaration:
153
155
154
156
has Bool $.done is rw;
155
157
156
- X < traits, is rw >
158
+ X < | traits, is rw>
157
159
158
160
The C < is rw > trait causes the generated accessor method to return something
159
161
external code can modify to change the value of the attribute.
160
162
161
163
= head1 Methods
162
164
163
- X < methods >
164
- X < classes, methods >
165
+ X < | methods>
166
+ X < | classes, methods>
165
167
166
168
While attributes give objects state, methods give objects behaviors. Ignore
167
169
the C < new > method temporarily; it's a special type of method. Consider the
@@ -172,7 +174,7 @@ dependency list.
172
174
push @!dependencies, $dependency;
173
175
}
174
176
175
- X < invocant >
177
+ X < | invocant>
176
178
177
179
In many ways, this looks a lot like a C < sub > declaration. However, there are
178
180
two important differences. First, declaring this routine as a method adds it to
@@ -198,7 +200,7 @@ It takes no parameters, working instead with the object's attributes. First, it
198
200
checks if the task has already completed by checking the C < $!done > attribute.
199
201
If so, there's nothing to do.
200
202
201
- X < operators, . >
203
+ X < | operators, .>
202
204
203
205
Otherwise, the method performs all of the task's dependencies, using the C < for >
204
206
construct to iterate over all of the items in the C < @!dependencies > attribute.
@@ -217,7 +219,7 @@ task.
217
219
218
220
= head1 Constructors
219
221
220
- X < constructors >
222
+ X < | constructors>
221
223
222
224
Perl 6 is rather more liberal than many languages in the area of constructors.
223
225
A constructor is anything that returns an instance of the class. Furthermore,
@@ -229,8 +231,8 @@ this example does:
229
231
return self.bless(*, :&callback, :@dependencies);
230
232
}
231
233
232
- X < objects, bless >
233
- X < bless >
234
+ X < | objects, bless>
235
+ X < | bless>
234
236
235
237
The biggest difference between constructors in Perl 6 and constructors in
236
238
languages such as C# and Java is that rather than setting up state on a somehow
@@ -303,6 +305,7 @@ attribute accessors.
303
305
TODO: the example here is rather bad, and needs to be replaced (or much
304
306
improved). See L < https://github.com/perl6/book/issues/58 > for discussion.
305
307
308
+ = begin code
306
309
class Employee {
307
310
has $.salary;
308
311
@@ -321,10 +324,12 @@ improved). See L<https://github.com/perl6/book/issues/58> for discussion.
321
324
~ $.known_languages[0] ~ '.';
322
325
}
323
326
}
327
+ = end code
324
328
325
329
Now any object of type Programmer can make use of the methods and accessors
326
330
defined in the Employee class as though they were from the Programmer class.
327
331
332
+ = begin code
328
333
my $programmer = Programmer.new(
329
334
salary => 100_000,
330
335
known_languages => <Perl5 Perl6 Erlang C++>,
@@ -333,13 +338,15 @@ defined in the Employee class as though they were from the Programmer class.
333
338
334
339
$programmer.code_to_solve('halting problem');
335
340
$programmer.pay();
341
+ = end code
336
342
337
343
= head2 Overriding Inherited Methods
338
344
339
345
Of course, classes can override methods and attributes defined by parent
340
346
classes by defining their own. The example below demonstrates the C < Baker > class
341
347
overriding the C < Cook > 's C < cook > method.
342
348
349
+ = begin code
343
350
class Cook is Employee {
344
351
has @.utensils is rw;
345
352
has @.cookbooks is rw;
@@ -372,6 +379,7 @@ overriding the C<Cook>'s C<cook> method.
372
379
salary => 50000);
373
380
374
381
$baker.cook('brioche'); # Baking a tasty brioche
382
+ = end code
375
383
376
384
Because the dispatcher will see the C < cook > method on C < Baker > before it moves up to
377
385
the parent class the C < Baker > 's C < cook > method will be called.
@@ -384,6 +392,7 @@ looking up a method to search for. As a side note, Perl 6 uses the C3
384
392
algorithm to linearize the multiple inheritance hierarchies, which is a
385
393
significant improvement over Perl 5's approach to handling multiple inheritance.
386
394
395
+ = begin code
387
396
class GeekCook is Programmer is Cook {
388
397
method new( *%params ) {
389
398
%params<cookbooks> //= []; # remove once Rakudo fully supports autovivification
@@ -401,6 +410,7 @@ significant improvement over Perl 5's approach to handling multiple inheritance.
401
410
402
411
$geek.cook('pizza');
403
412
$geek.code_to_solve('P =? NP');
413
+ = end code
404
414
405
415
Now all the methods made available by both the Programmer class and the Cook
406
416
class are available from the GeekCook class.
@@ -429,16 +439,13 @@ we can ask it a few questions:
429
439
430
440
The output can look like this:
431
441
432
- = begin screen
433
-
442
+ = for output
434
443
It's an employee
435
444
Programmer()
436
445
Programmer.new(known_languages => ["Perl", "Python", "Pascal"],
437
446
favorite_editor => "gvim", salary => "too small")
438
447
code_to_solve, known_languages, favorite_editor
439
448
440
- = end screen
441
-
442
449
The first two tests each smart-match against a class name. If the object is
443
450
of that class, or of an inheriting class, it returns true. So the object in
444
451
question is of class C < Employee > or one that inherits from it, but not
@@ -464,6 +471,7 @@ is actually a method call on the I<meta class>, which is a class managing the
464
471
properties of the C < Employee > class - or any other class you are interested
465
472
in. This meta class enables other ways of introspection too:
466
473
474
+ = for code
467
475
say $o.^attributes.join(', ');
468
476
say $o.^parents.join(', ');
469
477
0 commit comments