/
Agnostic.pm6
130 lines (89 loc) · 3.33 KB
/
Agnostic.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use v6.c;
use Hash::Agnostic:ver<0.0.3>:auth<cpan:ELIZABETH>;
role Map::Agnostic:ver<0.0.2>:auth<cpan:ELIZABETH>
does Hash::Agnostic
{
has int $!initialized;
#---- Methods supplied by Map::Agnostic needed by Hash::Agnostic ---------------
method ASSIGN-KEY(\key, \value) {
$!initialized
?? (die "Cannot change key '{key}' in an immutable {self.^name}")
!! self.INIT-KEY(key, value)
}
method BIND-KEY(\key, \value) {
X::Bind.new(target => self.^name).throw;
}
method DELETE-KEY(\key) {
die "Can not remove values from a {self.^name}";
}
multi method STORE(::?ROLE:D: \iterable, :$INITIALIZE!) {
callsame;
$!initialized = 1;
self
}
#---- Methods needed by Map::Agnostic ------------------------------------------
method INIT-KEY(\key, \value) { ... }
#---- Methods not allowed by Maps ----------------------------------------------
method append(|) {
die "Can not append values to a {self.^name}";
}
method grab(|) {
die "Can not grab values from a {self.^name}";
}
method push(|) {
die "Can not push values to a {self.^name}";
}
}
=begin pod
=head1 NAME
Map::Agnostic - be a map without knowing how
=head1 SYNOPSIS
use Map::Agnostic;
class MyMap does Map::Agnostic {
method INIT-KEY($key,$value) { ... }
method AT-KEY($key) { ... }
method EXISTS-KEY($key) { ... }
method keys() { ... }
}
my %m is MyMap = a => 42, b => 666;
my %m is Map::Agnostic = ...;
=head1 DESCRIPTION
This module makes a C<Map::Agnostic> role available for those classes that
wish to implement the C<Associative> role as an immutable C<Map>. It
provides all of the C<Map> functionality while only needing to implement
4 methods:
=head2 Required Methods
=head3 method INIT-KEY
method INIT-KEY($key, $value) { ... }
Bind the given value to the given key in the map, and return the value.
This will only be called during initialization of the C<Map>. The functioality
is the same as the C<BIND-KEY> method, but it will only be called at
initialization time, whereas C<BIND-KEY> can be called at any time and will
fail.
=head3 method AT-KEY
method AT-KEY($key) { ... }
Return the value at the given key in the map.
=head3 method EXISTS-KEY
method EXISTS-KEY($key) { ... }
Return C<Bool> indicating whether the key exists in the map.
=head3 method keys
method keys() { ... }
Return the keys that currently exist in the map, in any order that is
most convenient.
=head2 Optional Methods (provided by role)
You may implement these methods out of performance reasons yourself, but you
don't have to as an implementation is provided by this role. They follow the
same semantics as the methods on the
L<Map object|https://docs.perl6.org/type/Map>.
In alphabetical order:
C<elems>, C<end>, C<gist>, C<Hash>, C<iterator>, C<kv>, C<list>, C<List>,
C<new>, C<pairs>, C<perl>, C<Slip>, C<STORE>, C<Str>, C<values>
=head1 AUTHOR
Elizabeth Mattijsen <liz@wenzperl.nl>
Source can be located at: https://github.com/lizmat/Map-Agnostic .
Comments and Pull Requests are welcome.
=head1 COPYRIGHT AND LICENSE
Copyright 2018 Elizabeth Mattijsen
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
=end pod
# vim: ft=perl6 expandtab sw=4