package SlackBuild::Registry::Version; use strict; use warnings; use Carp; use SlackBuild::Base qw(major minor patch tail string:ro); sub new { my $class = shift; my $self = bless {}, $class; if (my $s = shift) { croak "too many arguments" if @_; $self->parse($s); } return $self; } sub major_number { shift->major || 0 }; sub minor_number { shift->minor || 0 }; sub patch_number { shift->patch || 0 }; sub tail_string { shift->tail || '' }; sub parse { my ($self, $str) = @_; $self->{string} = $str; delete $self->{major}; delete $self->{minor}; delete $self->{patch}; delete $self->{tail}; if ($str =~ s/^(\d+)(.*)/$2/) { $self->major($1); if ($str =~ s/^\.(\d+)(.*)/$2/) { $self->minor($1); if ($str =~ s/^\.(\d+)(.*)/$2/) { $self->patch($1); } } } $self->tail($str); } sub cmp { my ($self, $other) = @_; $other = __PACKAGE__->new($other) unless ref($other); foreach my $part (map { "${_}_number" } qw(major minor patch)) { if (my $d = $self->${\$part} <=> $other->${\$part}) { return $d; } } return $self->tail_string cmp $other->tail_string; } use overload '""' => sub { shift->string }, 'cmp' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other); return $swap ? -$res : $res; }, '<=>' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other); return $swap ? -$res : $res; }, '==' => sub { my ($self, $other) = @_; my $res = $self->cmp($other) == 0; }, '!=' => sub { my ($self, $other) = @_; my $res = $self->cmp($other) != 0; }, '<' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other) < 0; return $swap ? !$res : $res; }, '<=' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other) <= 0; return $swap ? !$res : $res; }, '>' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other) > 0; return $swap ? !$res : $res; }, '>=' => sub { my ($self, $other, $swap) = @_; my $res = $self->cmp($other) >= 0; return $swap ? !$res : $res; }; 1;