RDF::Trine::VariableBindings - Variable bindings


RDF-Trine documentation Contained in the RDF-Trine distribution.

Index


Code Index:

NAME

Top

RDF::Trine::VariableBindings - Variable bindings

VERSION

Top

This document describes RDF::Trine::VariableBindings version 0.135

METHODS

Top

new ( \%bindings )
set ( $variable_name => $node )
copy_labels_from ( $vb )

Copies the labels from $vb, adding them to the labels for this object.

join ( $row )

Returns a new VariableBindings object based on the join of this object and $row. If the two variable binding objects cannot be joined, returns undef.

variables
project ( @keys )

Returns a new binding with values for only the keys listed.

as_string

Returns a string representation of the variable bindings.

label ( $label => $value )

Sets the named $label to $value for this variable bindings object. If no $value is given, returns the current label value, or undef if none exists.

AUTHOR

Top

 Gregory Todd Williams <gwilliams@cpan.org>

COPYRIGHT

Top


RDF-Trine documentation Contained in the RDF-Trine distribution.
# RDF::Trine::VariableBindings
# -----------------------------------------------------------------------------

package RDF::Trine::VariableBindings;

use strict;
use warnings;
use overload	'""'	=> sub { $_[0]->as_string };

my %VB_LABELS;

use Scalar::Util qw(blessed refaddr);

######################################################################

our ($VERSION);
BEGIN {
	$VERSION	= '0.135';
}

######################################################################

sub new {
	my $class		= shift;
	my $bindings	= shift;
	my $self		= bless( { %$bindings }, $class );
	
	if (blessed($bindings) and $bindings->isa('RDF::Trine::VariableBindings')) {
		my $addr	= refaddr($bindings);
		if (ref($VB_LABELS{ $addr })) {
			$VB_LABELS{ refaddr($self) }	= { %{ $VB_LABELS{ $addr } } };
		}
	}
	
	return $self;
}

sub set {
	my $self	= shift;
	my $name	= shift;
	my $node	= shift;
	$self->{ $name }	= $node;
}

sub copy_labels_from {
	my $self		= shift;
	my $rowa		= shift;
	my $self_labels	= $VB_LABELS{ refaddr($self) };
	my $a_labels	= $VB_LABELS{ refaddr($rowa) };
	if ($self_labels or $a_labels) {
		$self_labels	||= {};
		$a_labels		||= {};
		my %new_labels	= ( %$self_labels, %$a_labels );
		
		if (exists $new_labels{'origin'}) {
			my %origins;
			foreach my $o (@{ $self_labels->{'origin'} || [] }) {
				$origins{ $o }++;
			}
			foreach my $o (@{ $a_labels->{'origin'} || [] }) {
				$origins{ $o }++;
			}
			$new_labels{'origin'}	= [ keys %origins ];
		}
		
		$VB_LABELS{ refaddr($self) }	= \%new_labels;
	}
}

sub join {
	my $self	= shift;
	my $class	= ref($self);
	my $rowb	= shift;
	
	my %keysa;
	my @keysa	= keys %$self;
	@keysa{ @keysa }	= (1) x scalar(@keysa);
	my @shared	= grep { exists $keysa{ $_ } } (keys %$rowb);
	foreach my $key (@shared) {
		my $val_a	= $self->{ $key };
		my $val_b	= $rowb->{ $key };
		next unless (defined($val_a) and defined($val_b));
		my $equal	= (refaddr($val_a) == refaddr($val_b)) || $val_a->equal( $val_b );
		unless ($equal) {
			return undef;
		}
	}
	
	my $row	= { (map { $_ => $self->{$_} } grep { defined($self->{$_}) } keys %$self), (map { $_ => $rowb->{$_} } grep { defined($rowb->{$_}) } keys %$rowb) };
	my $joined	= $class->new( $row );
	$joined->copy_labels_from( $self );
	$joined->copy_labels_from( $rowb );
	
	return $joined;
}

sub variables {
	my $self	= shift;
	return (keys %$self);
}

sub project {
	my $self	= shift;
	my $class	= ref($self);
	my @keys	= @_;
	my %data	= map { $_ => $self->{ $_ } } @keys;
	my $p		= $class->new( \%data );
	
	my $addr	= refaddr($self);
	if (ref($VB_LABELS{ $addr })) {
		$VB_LABELS{ refaddr($p) }	= { %{ $VB_LABELS{ $addr } } };
	}
	
	return $p;
}

sub as_string {
	my $self	= shift;
	my @keys	= sort keys %$self;
	my $string	= sprintf('{ %s }', CORE::join(', ', map { CORE::join('=', $_, ($self->{$_}) ? $self->{$_}->as_string : '()') } (@keys)));
	return $string;
}

sub label {
	my $self	= shift;
	my $addr	= refaddr($self);
	my $label_name	= shift;
	if (@_) {
		my $value	= shift;
		$VB_LABELS{ $addr }{ $label_name }	= $value;
	}
	
	my $labels	= $VB_LABELS{ $addr };
	if (ref($labels)) {
		my $value	= $labels->{ $label_name };
		return $value;
	} else {
		return;
	}
}

sub _labels {
	my $self	= shift;
	my $addr	= refaddr($self);
	my $labels	= $VB_LABELS{ $addr };
	return $labels;
}

sub DESTROY {
	my $self	= shift;
	my $addr	= refaddr( $self );
	delete $VB_LABELS{ $addr };
	return;
}

1;

__END__