stuff
[gitmo/Moose.git] / t / 031_mixin_example.t
CommitLineData
505c6fac 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More tests => 1;
7
8BEGIN {
9 use_ok('Moose');
10}
11
12=pod
13
14This test demonstrates how simple it is to create Scala Style
15Class Mixin Composition. Below is an example taken from the
16Scala web site's example section, and trancoded to Class::MOP.
17
18NOTE:
19We require SUPER for this test to handle the issue with SUPER::
20being determined at compile time.
21
22L<http://scala.epfl.ch/intro/mixin.html>
23
24A class can only be used as a mixin in the definition of another
25class, if this other class extends a subclass of the superclass
26of the mixin. Since ColoredPoint3D extends Point3D and Point3D
27extends Point2D which is the superclass of ColoredPoint2D, the
28code above is well-formed.
29
30 class Point2D(xc: Int, yc: Int) {
31 val x = xc;
32 val y = yc;
33 override def toString() = "x = " + x + ", y = " + y;
34 }
35
36 class ColoredPoint2D(u: Int, v: Int, c: String) extends Point2D(u, v) {
37 val color = c;
38 def setColor(newCol: String): Unit = color = newCol;
39 override def toString() = super.toString() + ", col = " + color;
40 }
41
42 class Point3D(xc: Int, yc: Int, zc: Int) extends Point2D(xc, yc) {
43 val z = zc;
44 override def toString() = super.toString() + ", z = " + z;
45 }
46
47 class ColoredPoint3D(xc: Int, yc: Int, zc: Int, col: String)
48 extends Point3D(xc, yc, zc)
49 with ColoredPoint2D(xc, yc, col);
50
51
52 Console.println(new ColoredPoint3D(1, 2, 3, "blue").toString())
53
54 "x = 1, y = 2, z = 3, col = blue"
55
56=cut
57
58{
59 package Point2D;
60 use metaclass;
61
62 Point2D->meta->add_attribute('$x' => (
63 accessor => 'x',
64 init_arg => 'x',
65 ));
66
67 Point2D->meta->add_attribute('$y' => (
68 accessor => 'y',
69 init_arg => 'y',
70 ));
71
72 sub new {
73 my $class = shift;
74 $class->meta->new_object(@_);
75 }
76
77 sub toString {
78 my $self = shift;
79 "x = " . $self->x . ", y = " . $self->y;
80 }
81
82 package ColoredPoint2D;
83 our @ISA = ('Point2D');
84
85 ColoredPoint2D->meta->add_attribute('$color' => (
86 accessor => 'color',
87 init_arg => 'color',
88 ));
89
90 sub toString {
91 my $self = shift;
92 $self->SUPER() . ', col = ' . $self->color;
93 }
94
95 package Point3D;
96 our @ISA = ('Point2D');
97
98 Point3D->meta->add_attribute('$z' => (
99 accessor => 'z',
100 init_arg => 'z',
101 ));
102
103 sub toString {
104 my $self = shift;
105 $self->SUPER() . ', z = ' . $self->z;
106 }
107
108 package ColoredPoint3D;
109 our @ISA = ('Point3D');
110
111 ::with('ColoredPoint2D');
112
113}
114
115my $colored_point_3d = ColoredPoint3D->new(x => 1, y => 2, z => 3, color => 'blue');
116isa_ok($colored_point_3d, 'ColoredPoint3D');
117isa_ok($colored_point_3d, 'Point3D');
118isa_ok($colored_point_3d, 'Point2D');
119
120is($colored_point_3d->toString(),
121 'x = 1, y = 2, z = 3, col = blue',
122 '... got the right toString method');
123