1mixin(3pm) User Contributed Perl Documentation mixin(3pm)
2
3
4
6 mixin - Mix-in inheritance, an alternative to multiple inheritance
7
9 package Dog;
10 sub speak { print "Bark!\n" }
11 sub new { my $class = shift; bless {}, $class }
12
13 package Dog::Small;
14 use base 'Dog';
15 sub speak { print "Yip!\n"; }
16
17 package Dog::Retriever;
18 use mixin::with 'Dog';
19 sub fetch { print "Get your own stinking $_[1]\n" }
20
21 package Dog::Small::Retriever;
22 use base 'Dog::Small';
23 use mixin 'Dog::Retriever';
24
25 my $small_retriever = Dog::Small::Retriever->new;
26 $small_retriever->speak; # Yip!
27 $small_retriever->fetch('ball'); # Get your own stinking ball
28
30 NOTE You probably want to look into the similar but superior concept of
31 traits/roles instead. See "SEE ALSO" for suggested modules.
32
33 Mixin inheritance is an alternative to the usual multiple-inheritance
34 and solves the problem of knowing which parent will be called. It also
35 solves a number of tricky problems like diamond inheritence.
36
37 The idea is to solve the same sets of problems which MI solves without
38 the problems of MI. For all practical purposes you can think of a
39 mixin as multiple inheritance without the actual inheritance.
40
41 Mixins are a band-aid for the problems of MI. A better solution is to
42 use traits (called "Roles" in Perl 6), which are like mixins on
43 steroids. Class::Trait implements this.
44
45 Using a mixin class
46 There are two steps to using a mixin-class.
47
48 First, make sure you are inherited from the class with which the mixin-
49 class is to be mixed.
50
51 package Dog::Small::Retriever;
52 use base 'Dog::Small';
53
54 Since Dog::Small isa Dog, that does it. Then simply mixin the new
55 functionality
56
57 use mixin 'Dog::Retriever';
58
59 and now you can use fetch().
60
61 Writing a mixin class
62 See mixin::with.
63
64 Mixins, Inheritance and SUPER
65 A class which uses a mixin does not inherit from it. However, through
66 some clever trickery, "SUPER" continues to work. Here's an example.
67
68 {
69 package Parent;
70 sub foo { "Parent" }
71 }
72
73 {
74 package Middle;
75 use mixin::with "Parent";
76
77 sub foo {
78 my $self = shift;
79 return $self->SUPER::foo(), "Middle";
80 }
81 }
82
83 {
84 package Child;
85 use base "Parent";
86 use mixin "Middle";
87
88 sub foo {
89 my $self = shift;
90 return $self->SUPER::foo(), "Child";
91 }
92 }
93
94 print join " ", Child->foo; # Parent Middle Child
95
96 This will print "Parent Middle Child". You'll note that this is the
97 same result if Child inherited from Middle and Middle from Parent. Its
98 also the same result if Child multiply inherited from Middle and Parent
99 but NOT if it inherited from Parent then Middle. The advantage of
100 mixins vs multiple inheritance is such ambiguities do not exist.
101
102 Note that even though both the Child and Middle define foo() the Middle
103 mixin does not overwrite Child's foo(). A mixin does not simply export
104 its methods into the mixer and thus does not blow over existing
105 methods.
106
108 A mixin will not warn if the mixin and the user define the same method.
109
111 Michael G Schwern <schwern@pobox.com>
112
114 Copyright 2002-2015 by Michael G Schwern
115
116 This library is free software; you can redistribute it and/or modify it
117 under the same terms as Perl itself.
118
119 <http://dev.perl.org/licenses/>
120
122 Role::Tiny - A stand alone implementation of traits/roles, like mixins
123 but better.
124
125 Moose::Role - Moose's implementation of traits/roles.
126
127 mro and Class::C3 make multiple inheritance work more sensibly.
128
129
130
131perl v5.38.0 2023-07-21 mixin(3pm)