summaryrefslogtreecommitdiff
path: root/lib/Data/MultiValued/Ranges.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Data/MultiValued/Ranges.pm')
-rw-r--r--lib/Data/MultiValued/Ranges.pm142
1 files changed, 131 insertions, 11 deletions
diff --git a/lib/Data/MultiValued/Ranges.pm b/lib/Data/MultiValued/Ranges.pm
index 9c69626..7193df6 100644
--- a/lib/Data/MultiValued/Ranges.pm
+++ b/lib/Data/MultiValued/Ranges.pm
@@ -6,7 +6,24 @@ use MooseX::Types::Moose qw(Num Str Undef Any);
use Data::MultiValued::Exceptions;
use Data::MultiValued::RangeContainer;
-# ABSTRACT: Handle values with tags and validity ranges
+# ABSTRACT: Handle values with validity ranges
+
+=head1 SYNOPSIS
+
+ use Data::MultiValued::Ranges;
+
+ my $obj = Data::MultiValued::Ranges->new();
+ $obj->set({
+ from => 10,
+ to => 20,
+ value => 'foo',
+ });
+ say $obj->get({at => 15}); # prints 'foo'
+ say $obj->get({at => 35}); # dies
+
+=head1 METHODS
+
+=cut
has _storage => (
is => 'rw',
@@ -19,18 +36,39 @@ sub _build__storage {
Data::MultiValued::RangeContainer->new();
}
-sub _rebless_storage {
- my ($self) = @_;
+=head2 C<set>
- bless $self->{_storage},'Data::MultiValued::RangeContainer';
-}
+ $obj->set({ from => $min, to => $max, value => $the_value });
-sub _as_hash {
- my ($self) = @_;
+Stores the given value for the given range. Throws
+L<Data::MultiValued::Exceptions::BadRange> if C<< $min > $max >>.
- my %ret = %{$self->_storage};
- return {_storage=>\%ret};
-}
+The range is defined as C<< Num $x : $min <= $x < $max >>. A C<< from
+=> undef >> means "from -Inf", and a C<< to => undef >> means "to
++Inf". Not passing in C<from> or C<to> is equivalent to passing
+C<undef>.
+
+If the given range intersects existing ranges, these are spliced to
+avoid overlaps. In other words:
+
+ $obj->set({
+ from => 10,
+ to => 20,
+ value => 'foo',
+ });
+ $obj->set({
+ from => 15,
+ to => 25,
+ value => 'bar',
+ });
+ say $obj->get({at => 12}); # prints 'foo'
+ say $obj->get({at => 15}); # prints 'bar'
+ say $obj->get({at => 25}); # dies
+
+No cloning is done: if you pass in a reference, the reference is
+just stored.
+
+=cut
sub set {
my ($self,%args) = validated_hash(
@@ -40,10 +78,27 @@ sub set {
value => { isa => Any, },
);
- $self->_storage->set_or_create(\%args)
+ $self->_storage->get_or_create(\%args)
->{value} = $args{value};
}
+=head2 C<get>
+
+ my $value = $obj->get({ at => $point });
+
+Retrieves the value for the given point. Throws a
+L<Data::MultiValued::Exceptions::RangeNotFound> exception if no ranges
+exist in this object that include the point (remember that a range
+does not include its C<to> point).
+
+A C<< at => undef >> means "at -Inf". Not passing in C<at> is
+equivalent to passing C<undef>.
+
+No cloning is done: if a reference was stored, you get it back
+untouched.
+
+=cut
+
sub get {
my ($self,%args) = validated_hash(
\@_,
@@ -54,6 +109,34 @@ sub get {
->{value};
}
+=head2 C<clear>
+
+ $obj->clear({ from => $min, to => $max });
+
+Deletes all values for the given range. Throws
+L<Data::MultiValued::Exceptions::BadRange> if C<< $min > $max >>.
+
+A C<< from => undef >> means "from -Inf", and a C<< to => undef >>
+means "to +Inf". Not passing in C<from> or C<to> is equivalent to
+passing C<undef>. Thus, C<< $obj->clear() >> clears everything.
+
+If the given range intersects existing ranges, these are spliced. In
+other words:
+
+ $obj->set({
+ from => 10,
+ to => 20,
+ value => 'foo',
+ });
+ $obj->clear({
+ from => 15,
+ to => 25,
+ });
+ say $obj->get({at => 12}); # prints 'foo'
+ say $obj->get({at => 15}); # dies
+
+=cut
+
sub clear {
my ($self,%args) = validated_hash(
\@_,
@@ -64,5 +147,42 @@ sub clear {
$self->_storage->clear(\%args);
}
+=head1 Serialisation helpers
+
+These are used through
+L<Data::MultiValued::UglySerializationHelperRole>.
+
+=head2 C<_rebless_storage>
+
+Blesses the storage into L<Data::MultiValued::RangeContainer>.
+
+=cut
+
+sub _rebless_storage {
+ my ($self) = @_;
+
+ bless $self->{_storage},'Data::MultiValued::RangeContainer';
+}
+
+
+=head2 C<_as_hash>
+
+Returns the internal representation with no blessed hashes, with as
+few copies as possible.
+
+=cut
+
+sub _as_hash {
+ my ($self) = @_;
+
+ my %ret = %{$self->_storage};
+ return {_storage=>\%ret};
+}
+
+=head1 SEE ALSO
+
+L<Data::MultiValued::RangeContainer>, L<Data::MultiValued::Exceptions>
+
+=cut
1;