1use Perl6::Say;
2
3package Wax::Floor;
4use Class::Std;
5{
6    my %name_of      :ATTR( :get<name> :set<name> );
7    my %patent_of    :ATTR( get => 'patent' );
8
9    sub BUILD {
10        my ($self, $ident, $arg_ref) = @_;
11
12        $name_of{$ident}   = $arg_ref->{name};
13        $patent_of{$ident} = $arg_ref->{patent};
14    }
15
16    sub describe :CUMULATIVE {
17        my ($self) = @_;
18
19        ::say "The floor wax $name_of{ident $self} (patent: $patent_of{ident $self})";
20    }
21
22    sub features :CUMULATIVE {
23        return ('Long-lasting', 'Non-toxic', 'Polymer-based');
24    }
25
26    sub active_ingredients :CUMULATIVE(BASE FIRST) {
27        return "Wax: paradichlorobenzene,  hydrogen peroxide, cyanoacrylate\n";
28    }
29}
30
31package Topping::Dessert;
32use Class::Std;
33{
34    my (%name_of, %flavour_of) :ATTRS;
35
36    sub BUILD {
37        my ($self, $ident, $arg_ref) = @_;
38
39        $name_of{$ident}    = $arg_ref->{name};
40        $flavour_of{$ident} = $arg_ref->{flavour};
41    }
42
43    sub describe :CUMULATIVE {
44        my ($self) = @_;
45
46        ::say "The dessert topping $name_of{ident $self} ",
47              "with that great $flavour_of{ident $self} taste!";
48    }
49
50    sub features :CUMULATIVE {
51        return ('Multi-purpose', 'Time-saving', 'Easy-to-use');
52    }
53
54    sub active_ingredients:CUMULATIVE(BASE FIRST) {
55        return "Topping: sodium hypochlorite, isobutyl ketone, ethylene glycol\n";
56    }
57}
58
59package Shimmer;
60use base qw( Wax::Floor  Topping::Dessert );
61use Class::Std;
62{
63    my %name_of    :ATTR;
64    my %patent_of  :ATTR;
65
66    sub BUILD {
67        my ($self, $ident, $arg_ref) = @_;
68
69        $name_of{$ident}   = $arg_ref->{name};
70        $patent_of{$ident} = $arg_ref->{patent};
71    }
72
73    sub describe :CUMULATIVE {
74        my ($self) = @_;
75
76        ::say "New $name_of{ident $self} (patent: $patent_of{ident $self}). Combining...";
77    }
78
79    sub features :CUMULATIVE {
80        return ('Multi-purpose', 'Time-saving', 'Easy-to-use');
81    }
82
83    sub active_ingredients:CUMULATIVE(BASE FIRST) {
84        return "Binder: aromatic hydrocarbons, xylene, methyl mercaptan\n";
85    }
86
87    sub DEMOLISH {
88        ::say 'Good-bye cruel world!';
89    }
90
91    sub as_str : STRINGIFY { return "SHIMMER!!!!!"; }
92    sub as_bool : BOOLIFY NUMERIFY { return 0; }
93}
94
95my $product
96    = Shimmer->new({ name=>'Shimmer', patent=>1562516251, flavour=>'Vanilla'});
97
98print "As string:  $product\n";
99print "As number:  ", 0+$product, "\n";
100print "As boolean: ", $product ? "true\n" : "false\n";
101
102$product->describe();
103
104my @features = Shimmer->features();
105::say "Shimmer is the @features alternative!";
106
107my $ingredients = $product->active_ingredients();
108print "Contains:\n$ingredients";
109print "From ", 0+$ingredients, " sources:\n";
110print map {"\t$_\n"} keys %$ingredients;
111use Data::Dumper 'Dumper';
112warn Dumper \%$ingredients;
113
114my $obj = Shimmer->new({patent=>12345, name=>'Shimmer'});
115print "Patent: ", $obj->get_patent(), "\n";
116print "Name:   ", $obj->get_name(), "\n";
117$obj->set_name("Glimmer");
118print "Name:   ", $obj->get_name(), "\n";
119
120eval { $obj->set_patent(98765) } or print $@;
121eval { $obj->set_name() } or print $@;
122
123