use v5.14;
use warnings;
=head1 NAME
Attean::TermMap - Mapping terms to new terms
=head1 VERSION
This document describes Attean::TermMap version 0.030
=head1 SYNOPSIS
use v5.14;
use Attean;
my $m = Attean::TermMap->short_blank_map;
my $new_blank = $m->map( Attean::Blank->new('abcdefg') );
say $new_blank->ntriples_string; # _:a
=head1 DESCRIPTION
The Attean::TermMap class represents a one-way mapping process from and to
L<Attean::API::Term> objects. This mapping may rename the blank identifiers,
skolemize nodes, or map the nodes in some other, custom way.
It conforms to the L<Attean::API::Mapper> role.
=head1 ATTRIBUTES
=over 4
=item C<< mapper >>
A CODE reference that will map L<Attean::API::Term> objects to (possibly different)
term objects.
=back
=head1 CLASS METHODS
=over 4
=cut
package Attean::TermMap 0.030 {
use Moo;
use Types::Standard qw(CodeRef);
use Attean::API::Binding;
use UUID::Tiny ':std';
use namespace::clean;
with 'Attean::Mapper';
has 'mapper' => (is => 'ro', isa => CodeRef, default => sub { shift }, required => 1);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
if (scalar(@_) == 1) {
return $class->$orig(mapper => shift);
}
return $class->$orig(@_);
};
=item C<< canonicalization_map >>
Returns a new L<Attean::TermMap> that canonicalizes recognized typed
L<Attean::API::Literal> values.
=cut
sub canonicalization_map {
my $class = shift;
my %map;
return $class->new(mapper => sub {
my $term = shift;
return $term unless ($term->does('Attean::API::Literal'));
if ($term->does('Attean::API::CanonicalizingLiteral')) {
my $c = eval { $term->canonicalized_term };
return ($@) ? undef : $c;
}
return $term;
});
}
=item C<< uuid_blank_map >>
Returns a new L<Attean::TermMap> that renames blank nodes with UUID values.
=cut
sub uuid_blank_map {
my $class = shift;
my %map;
return $class->new(mapper => sub {
my $term = shift;
return $term unless ($term->does('Attean::API::Blank'));
my $id = $term->value;
return $map{$id} if (defined($map{$id}));
my $uuid = unpack('H*', create_uuid());
my $new = Attean::Blank->new( 'b' . $uuid );
$map{$id} = $new;
return $new;
});
}
=item C<< short_blank_map >>
Returns a new L<Attean::TermMap> that renames blank nodes with short
alphabetic names (e.g. _:a, _:b).
=cut
sub short_blank_map {
my $class = shift;
my %map;
my $next = 'a';
return $class->new(mapper => sub {
my $term = shift;
return $term unless ($term->does('Attean::API::Blank'));
my $id = $term->value;
if (defined(my $t = $map{$id})) {
return $t;
} else {
my $new = Attean::Blank->new( $next++ );
$map{$id} = $new;
return $new;
}
});
}
=item C<< rewrite_map( \%map ) >>
Given C<< %map >> whose keys are term C<< as_string >> serializations, and
objects are L<Attean::API::Term> objects, returns a new term map object that
maps terms matching entries in C<< %map >>, and all other terms to themselves.
=cut
sub rewrite_map {
my $class = shift;
my $map = shift;
return $class->new(mapper => sub {
my $term = shift;
return $map->{ $term->as_string } if (exists $map->{ $term->as_string });
return $term;
});
}
=back
=head1 METHODS
=over 4
=item C<< map( $term ) >>
Returns the term that is mapped to by the supplied C<< $term >>.
=cut
sub map {
my $self = shift;
my $term = shift;
return $self->mapper->( $term );
}
=item C<< binding_mapper >>
Returns a mapping function reference that maps L<Attean::API::Binding>
objects by mapping their constituent mapped L<Attean::API::Term> objects.
=cut
sub binding_mapper {
my $self = shift;
return sub {
my $binding = shift;
return $binding->apply_map($self);
}
}
}
1;
__END__
=back
=head1 BUGS
Please report any bugs or feature requests to through the GitHub web interface
at L<https://github.com/kasei/attean/issues>.
=head1 SEE ALSO
=head1 AUTHOR
Gregory Todd Williams C<< <gwilliams@cpan.org> >>
=head1 COPYRIGHT
Copyright (c) 2014--2020 Gregory Todd Williams.
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut