Attean

 view release on metacpan or  search on metacpan

lib/AtteanX/Functions/CompositeMaps.pm  view on Meta::CPAN

	sub mapCreate_agg_start {
		my $model			= shift;
		my $active_graph	= shift;
		return {
			values => {}
		};
	}

=item C<< mapCreate_agg_process($thunk, $key, $value) >>

=cut
	sub mapCreate_agg_process {
		my $thunk	= shift;
		my ($key)	= shift;
		my $value	= shift;
		$thunk->{'values'}{$key->value}	= $value;
	}

=item C<< mapCreate_agg_finalize($thunk) >>

=cut
	sub mapCreate_agg_finalize {
		my $thunk	= shift;
		my %terms	= @{ $thunk->{'values' }};
		return map_to_lex(%terms);
	}

=item C<< register() >>

=cut
	sub register {
		Attean->register_datatype_role(
			$MAP_TYPE_IRI	=> 'AtteanX::Functions::CompositeMaps::MapLiteral'
		);
		
		Attean->register_global_functional_form(
			"${CDT_BASE}Map" => \&mapCreate,
			"${CDT_BASE}mapCreate" => \&mapCreate,
			"${CDT_BASE}put" => \&mapPut,
		);
		Attean->register_global_function(
			"${CDT_BASE}mapGet" => \&mapGet,
			"${CDT_BASE}mapSize" => \&mapSize,
			"${CDT_BASE}keys" => \&mapKeys,
			"${CDT_BASE}remove" => \&mapRemove,
			"${CDT_BASE}containsKey" => \&mapContains,
			"${CDT_BASE}merge" => \&mapMerge,
		);

		Attean->register_global_aggregate(
			"${CDT_BASE}mapAgg" => {
				start		=> \&mapCreate_agg_start,
				process		=> \&mapCreate_agg_process,
				finalize	=> \&mapCreate_agg_finalize,
			},
		);
	}
}

package AtteanX::Functions::CompositeMaps::MapLiteral {
	use Scalar::Util qw(blessed looks_like_number);
	use List::Util qw(min);

	use Moo::Role;

	sub equals {
		my $lhs	= shift;
		my $rhs	= shift;
# 		warn "MAP EQUALS?";
# 		warn "- " . $lhs->as_string . "\n";
# 		warn "- " . $rhs->as_string . "\n";
		return 0 unless ($rhs->does('Attean::API::Literal') and $rhs->datatype->value eq $AtteanX::Functions::CompositeMaps::MAP_TYPE_IRI);
		my $lhs_size	= eval { AtteanX::Functions::CompositeMaps::mapSize(undef, undef, $lhs)->value };
		return 0 if ($@);
 		my $rhs_size	= eval { AtteanX::Functions::CompositeMaps::mapSize(undef, undef, $rhs)->value };
		return 0 if ($@);
		return 0 unless ($lhs_size == $rhs_size);
		
		my %lhs_map	= AtteanX::Functions::CompositeMaps::lex_to_map($lhs);
		my %rhs_map	= AtteanX::Functions::CompositeMaps::lex_to_map($rhs);
		
		my @lhs_keys	= sort(keys %lhs_map);
		my @rhs_keys	= sort(keys %rhs_map);
		
		# TODO: handle differing lexical forms for map keys here:

		my $seen_error	= 0;
		foreach my $i (0 .. $lhs_size-1) {
			return 0 unless ($lhs_keys[$i] eq $rhs_keys[$i]);
			my $key	= $lhs_keys[$i];
			my $lv	= $lhs_map{$key};
			my $rv	= $rhs_map{$key};
			if (not blessed($lv) and not blessed($rv)) {
				# both null
				next;
			} elsif (not blessed($lv) or not blessed($rv)) {
				return 0;
			}

			if ($lv->does('Attean::API::Blank') and $rv->does('Attean::API::Blank')) {
				if ($lv->value eq $rv->value) {
					next;
				} else {
					$seen_error++;
					next;
				}
			}

			return 0 unless ($lv->equals($rv));
		}
		if ($seen_error) {
			die 'TypeError';
		}
		return 1;
	}
	
	sub order {
		my $self	= shift;
		return _compare('order', $self, @_);
	}
	



( run in 0.882 second using v1.01-cache-2.11-cpan-0b5f733616e )