File Coverage

blib/lib/Attean/TermMap.pm
Criterion Covered Total %
statement 66 66 100.0
branch 15 16 93.7
condition n/a
subroutine 18 18 100.0
pod 6 6 100.0
total 105 106 99.0


line stmt bran cond sub pod time code
1 50     50   683 use v5.14;
  50         175  
2 50     50   263 use warnings;
  50         116  
  50         2184  
3              
4             =head1 NAME
5              
6             Attean::TermMap - Mapping terms to new terms
7              
8             =head1 VERSION
9              
10             This document describes Attean::TermMap version 0.032
11              
12             =head1 SYNOPSIS
13              
14             use v5.14;
15             use Attean;
16             my $m = Attean::TermMap->short_blank_map;
17             my $new_blank = $m->map( Attean::Blank->new('abcdefg') );
18             say $new_blank->ntriples_string; # _:a
19              
20             =head1 DESCRIPTION
21              
22             The Attean::TermMap class represents a one-way mapping process from and to
23             L<Attean::API::Term> objects. This mapping may rename the blank identifiers,
24             skolemize nodes, or map the nodes in some other, custom way.
25              
26             It conforms to the L<Attean::API::Mapper> role.
27              
28             =head1 ATTRIBUTES
29              
30             =over 4
31              
32             =item C<< mapper >>
33              
34             A CODE reference that will map L<Attean::API::Term> objects to (possibly different)
35             term objects.
36              
37             =back
38              
39             =head1 CLASS METHODS
40              
41             =over 4
42              
43             =cut
44              
45             use Moo;
46 50     50   274 use Types::Standard qw(CodeRef);
  50         122  
  50         308  
47 50     50   16613 use Attean::API::Binding;
  50         174  
  50         441  
48 50     50   24711 use UUID::Tiny ':std';
  50         112  
  50         1489  
49 50     50   289 use namespace::clean;
  50         112  
  50         10816  
50 50     50   374
  50         149  
  50         428  
51             with 'Attean::Mapper';
52             has 'mapper' => (is => 'ro', isa => CodeRef, default => sub { shift }, required => 1);
53            
54             around BUILDARGS => sub {
55             my $orig = shift;
56             my $class = shift;
57             if (scalar(@_) == 1) {
58             return $class->$orig(mapper => shift);
59             }
60             return $class->$orig(@_);
61             };
62              
63             =item C<< canonicalization_map >>
64              
65             Returns a new L<Attean::TermMap> that canonicalizes recognized typed
66             L<Attean::API::Literal> values.
67              
68             =cut
69              
70             my $class = shift;
71             my %map;
72 9     9 1 2009 return $class->new(mapper => sub {
73 9         14 my $term = shift;
74             return $term unless ($term->does('Attean::API::Literal'));
75 60     60   71
76 60 100       147 if ($term->does('Attean::API::CanonicalizingLiteral')) {
77             my $c = eval { $term->canonicalized_term };
78 7 100       92 return ($@) ? undef : $c;
79 1         17 }
  1         6  
80 1 50       72
81             return $term;
82             });
83 6         93 }
84 9         190  
85             =item C<< uuid_blank_map >>
86              
87             Returns a new L<Attean::TermMap> that renames blank nodes with UUID values.
88              
89             =cut
90              
91             my $class = shift;
92             my %map;
93             return $class->new(mapper => sub {
94 1     1 1 4070 my $term = shift;
95 1         3 return $term unless ($term->does('Attean::API::Blank'));
96             my $id = $term->value;
97 14     14   19 return $map{$id} if (defined($map{$id}));
98 14 100       23
99 6         80 my $uuid = unpack('H*', create_uuid());
100 6 100       17 my $new = Attean::Blank->new( 'b' . $uuid );
101             $map{$id} = $new;
102 4         12 return $new;
103 4         593 });
104 4         193 }
105 4         13  
106 1         25 =item C<< short_blank_map >>
107              
108             Returns a new L<Attean::TermMap> that renames blank nodes with short
109             alphabetic names (e.g. _:a, _:b).
110              
111             =cut
112              
113             my $class = shift;
114             my %map;
115             my $next = 'a';
116             return $class->new(mapper => sub {
117 1     1 1 1196 my $term = shift;
118 1         2 return $term unless ($term->does('Attean::API::Blank'));
119 1         2 my $id = $term->value;
120             if (defined(my $t = $map{$id})) {
121 14     14   15 return $t;
122 14 100       23 } else {
123 6         77 my $new = Attean::Blank->new( $next++ );
124 6 100       17 $map{$id} = $new;
125 2         6 return $new;
126             }
127 4         74 });
128 4         205 }
129 4         18  
130             =item C<< rewrite_map( \%map ) >>
131 1         8  
132             Given C<< %map >> whose keys are term C<< as_string >> serializations, and
133             objects are L<Attean::API::Term> objects, returns a new term map object that
134             maps terms matching entries in C<< %map >>, and all other terms to themselves.
135              
136             =cut
137              
138             my $class = shift;
139             my $map = shift;
140             return $class->new(mapper => sub {
141             my $term = shift;
142             return $map->{ $term->as_string } if (exists $map->{ $term->as_string });
143 12     12 1 30 return $term;
144 12         18 });
145             }
146 69     69   82  
147 69 100       173 =back
148 42         2176  
149 12         195 =head1 METHODS
150              
151             =over 4
152              
153             =item C<< map( $term ) >>
154              
155             Returns the term that is mapped to by the supplied C<< $term >>.
156              
157             =cut
158              
159             my $self = shift;
160             my $term = shift;
161             return $self->mapper->( $term );
162             }
163              
164             =item C<< binding_mapper >>
165 157     157 1 231  
166 157         178 Returns a mapping function reference that maps L<Attean::API::Binding>
167 157         275 objects by mapping their constituent mapped L<Attean::API::Term> objects.
168              
169             =cut
170              
171             my $self = shift;
172             return sub {
173             my $binding = shift;
174             return $binding->apply_map($self);
175             }
176             }
177             }
178 2     2 1 89  
179             1;
180 4     4   5  
181 4         12  
182             =back
183 2         8  
184             =head1 BUGS
185              
186             Please report any bugs or feature requests to through the GitHub web interface
187             at L<https://github.com/kasei/attean/issues>.
188              
189             =head1 SEE ALSO
190              
191              
192              
193             =head1 AUTHOR
194              
195             Gregory Todd Williams C<< <gwilliams@cpan.org> >>
196              
197             =head1 COPYRIGHT
198              
199             Copyright (c) 2014--2022 Gregory Todd Williams.
200             This program is free software; you can redistribute it and/or modify it under
201             the same terms as Perl itself.
202              
203             =cut