B
bill
I have a class that is implemented as a hashref, and furthermore,
the values for the corresponding hash are always scalars. I want
a sub to test for equality between any two instances of this class,
defined roughly as "two instances $x and $y are equal if $x->{
$field } and $y->{ $field } are equal for all instance fields
$field". I took a crack at this function, but it is so *ugly* that
I'm sure there must be a better way. I give my version below for
your mocking pleasure. Any pointers to a better implementation
would be much appreciated.
bill
# ...
BEGIN { # private subs
$_equals = sub {
my @args = @_[0, 1];
for my $field (@_fields) { # @_fields is defined earlier
my @vals = map $_->$field, @args;
my $n_defined = grep defined $_, @vals;
next if $n_defined == 0;
return 0 if $n_defined == 1;
if (2 == grep $_is_numeric($_), @vals) {
return 0 unless $vals[0] == $vals[1];
}
else {
return 0 unless $vals[0] eq $vals[1];
}
}
return 1;
};
$_is_numeric = sub {
# cribbed from a clpm post by Anno Siegel
use warnings 'all', FATAL => 'numeric';
return defined eval { $_[0] == 0 };
};
}
use overload '==' => $_equals, fallback => 1;
# ...
the values for the corresponding hash are always scalars. I want
a sub to test for equality between any two instances of this class,
defined roughly as "two instances $x and $y are equal if $x->{
$field } and $y->{ $field } are equal for all instance fields
$field". I took a crack at this function, but it is so *ugly* that
I'm sure there must be a better way. I give my version below for
your mocking pleasure. Any pointers to a better implementation
would be much appreciated.
bill
# ...
BEGIN { # private subs
$_equals = sub {
my @args = @_[0, 1];
for my $field (@_fields) { # @_fields is defined earlier
my @vals = map $_->$field, @args;
my $n_defined = grep defined $_, @vals;
next if $n_defined == 0;
return 0 if $n_defined == 1;
if (2 == grep $_is_numeric($_), @vals) {
return 0 unless $vals[0] == $vals[1];
}
else {
return 0 unless $vals[0] eq $vals[1];
}
}
return 1;
};
$_is_numeric = sub {
# cribbed from a clpm post by Anno Siegel
use warnings 'all', FATAL => 'numeric';
return defined eval { $_[0] == 0 };
};
}
use overload '==' => $_equals, fallback => 1;
# ...