Skip to content

Commit c6ac771

Browse files
committed
[objects] inheritance, object construction
1 parent 45054e8 commit c6ac771

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

lib/objects.pod

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,97 @@ certainly override them.
217217
218218
TODO: example
219219
220-
TODO: object construction, inheritance
220+
=head2 Inheritance
221+
222+
Classes can have I<parent classes>.
223+
224+
class Child is Parent1 is Parent2 { }
225+
226+
If a method is called on the child class, and the child class does not
227+
provide that method, the parents' method of the name is invoked instead,
228+
if it exists. The order by which parent classes are consulted is called the
229+
I<method resolution order> (mro). Perl 6 uses the
230+
L<C3 method resolution order|https://en.wikipedia.org/wiki/C3_linearization>.
231+
You can ask a type for its MRO through a call to its metaclass:
232+
233+
234+
say Parcel.^mro; # Parcel() Cool() Any() Mu()
235+
236+
If a class does not specify a parent class, L<Any> is assumed by default. All
237+
classes directly or indirectly derive from L<Mu>, the root of the type
238+
hierarchy.
239+
240+
All calls to public method are "virtual" in the C++ sense, wihch means that
241+
the actual type of an object determines which method to call, not the declared
242+
type.
243+
244+
=head2 Object Construction
245+
246+
Objects are generally created through methods calls, either on the type object
247+
or on another object of the same type.
248+
249+
Class L<Mu> provides a constructor method called L<new>, which takes named
250+
arguments and uses them to initialize public attributes.
251+
252+
class Point {
253+
has $.x;
254+
has $.y = 2 * $!x;
255+
}
256+
my $p = Point.new( x => 1, y => 2);
257+
# ^^^ inherited from class Mu
258+
259+
Mu.new calls method L<bless> on its invocant, passing along all the named
260+
arguments. C<bless> creates the new object, and then calls method C<BUILDALL>
261+
on it. C<BUILDALL> walks all subclasses in reverse method resolution order
262+
(ie from L<Mu> to most derived classes), and in each class checks for
263+
existence of a method named C<BUILD>. If it exists, it is called, again
264+
passing all named arguments from method C<new> to it. If not, the public
265+
attributes from this class are initialized from named arguments of the same
266+
name. In either case, if neither C<BUILD> nor the default mechanism has
267+
initialized the attribute, default values are applied (the C<2 * $!x> in the
268+
example above).
269+
270+
This object construction scheme has several implications for customized
271+
constructors. First, custom C<BUILD> methods should always be submethods,
272+
otherwise they break attribute initialization in subclasses. Second,
273+
C<BUILD> submethods can be used to run custom code at object construction
274+
time. They can also be used for creating aliases for attribute initialization:
275+
276+
class EncodedBuffer {
277+
has $.enc;
278+
has $.data;
279+
280+
submethod BUILD(:encoding(:$enc), :$data) {
281+
$!enc := $enc;
282+
$!data := $data;
283+
}
284+
}
285+
my $b1 = EncodedBuffer.new( encoding => 'UTF-8', data => [64, 65] );
286+
my $b2 = EncodedBuffer.new( enc => 'UTF-8', data => [64, 65] );
287+
# both enc and encoding are allowed now
288+
289+
Since passing arguments to a routine binds the argumenst to the parameters,
290+
a separate binding step is unnecessary if the attribute is used as parameter.
291+
So the example above yould also have been written as
292+
293+
submethod BUILD(:encoding(:$!enc), :$!data) {
294+
# nothing to do here anymore, the signature binding
295+
# does all the work for us.
296+
}
297+
298+
The third implication is that if you want a constructor that accepts positional
299+
arguments, you must write your own C<new> method:
300+
301+
class Point {
302+
has $.x;
303+
has $.y;
304+
method new($x, $y) {
305+
self.bless(*, :$x, :$y);
306+
}
307+
}
308+
309+
However this is considered poor practise, because it makes correct
310+
initialization of objects from subclasses much harder.
221311
222312
=head1 Roles
223313

0 commit comments

Comments
 (0)