Skip to content

Commit

Permalink
use keys instead of positioned parameters, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
xsawyerx committed Dec 28, 2012
1 parent 77ae850 commit 9cb2c6b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 115 deletions.
62 changes: 19 additions & 43 deletions lib/Algorithm/Diff/Callback.pm
Expand Up @@ -12,69 +12,45 @@ our $VERSION = '0.03';
our @EXPORT_OK = qw(diff_hashes diff_arrays); our @EXPORT_OK = qw(diff_hashes diff_arrays);


sub diff_hashes { sub diff_hashes {
my ( $old, $new, $del_cb, $add_cb, $changed_cb ) = @_; my ( $old, $new, %cbs ) = @_;
my @changed = ();


# check old and new hashes
ref $old eq 'HASH' or croak 'Arg 1 must be hashref'; ref $old eq 'HASH' or croak 'Arg 1 must be hashref';
ref $new eq 'HASH' or croak 'Arg 2 must be hashref'; ref $new eq 'HASH' or croak 'Arg 2 must be hashref';


# check callbacks my @changed = ();
{ foreach my $key ( keys %{$new} ) {
my $count = 3; if ( ! exists $old->{$key} ) {
foreach ( $del_cb, $add_cb, $changed_cb ) { exists $cbs{'added'}
if ( defined $_ ) { and $cbs{'added'}->( $key, $new->{$key} );
ref $_ eq 'CODE' or croak "Arg $count must be coderef or undef";
}

$count++;
}
}

# start doing the work
foreach my $cell ( keys %{$new} ) {
if ( ! exists $old->{$cell} ) {
$add_cb and $add_cb->( $cell, $new->{$cell} );
} else { } else {
push @changed, $cell; push @changed, $key;
} }
} }


foreach my $cell ( keys %{$old} ) { foreach my $key ( keys %{$old} ) {
if ( ! exists $new->{$cell} ) { if ( ! exists $new->{$key} ) {
$del_cb and $del_cb->( $cell, $old->{$cell} ); exists $cbs{'deleted'}
and $cbs{'deleted'}->( $key, $old->{$key} );
} }
} }


foreach my $changed (@changed) { foreach my $key (@changed) {
my $before = $old->{$changed} || ''; my $before = $old->{$key} || '';
my $after = $new->{$changed} || ''; my $after = $new->{$key} || '';


if ( $before ne $after ) { if ( $before ne $after ) {
$changed_cb and $changed_cb->( $changed, $before, $after ); exists $cbs{'changed'}
and $cbs{'changed'}->( $key, $before, $after );
} }
} }
} }


sub diff_arrays { sub diff_arrays {
my ( $old, $new, $del_cb, $add_cb ) = @_; my ( $old, $new, %cbs ) = @_;


# check old and new hashes
ref $old eq 'ARRAY' or croak 'Arg 1 must be arrayref'; ref $old eq 'ARRAY' or croak 'Arg 1 must be arrayref';
ref $new eq 'ARRAY' or croak 'Arg 2 must be arrayref'; ref $new eq 'ARRAY' or croak 'Arg 2 must be arrayref';


# check callbacks
{
my $count = 3;
foreach ( $del_cb, $add_cb ) {
if ( defined $_ ) {
ref $_ eq 'CODE' or croak "Arg $count must be coderef or undef";
}

$count++;
}
}

# normalize arrays # normalize arrays
my @old = uniq sort @{$old}; my @old = uniq sort @{$old};
my @new = uniq sort @{$new}; my @new = uniq sort @{$new};
Expand All @@ -86,9 +62,9 @@ sub diff_arrays {
my ( $change, undef, $value ) = @{$changeset}; my ( $change, undef, $value ) = @{$changeset};


if ( $change eq '+' ) { if ( $change eq '+' ) {
$add_cb and $add_cb->($value); exists $cbs{'added'} and $cbs{'added'}->($value);
} elsif ( $change eq '-' ) { } elsif ( $change eq '-' ) {
$del_cb and $del_cb->($value); exists $cbs{'deleted'} and $cbs{'deleted'}->($value);
} else { } else {
croak "Can't recognize change in changeset: '$change'"; croak "Can't recognize change in changeset: '$change'";
} }
Expand Down
2 changes: 1 addition & 1 deletion t/croak.t
Expand Up @@ -16,7 +16,7 @@ my @old = qw( one two );
my @new = qw( one four ); my @new = qw( one four );
$|++; $|++;


eval { diff_arrays( \@old, \@new, sub {}, sub {} ) }; eval { diff_arrays( \@old, \@new, added => sub {}, deleted => sub {} ) };
ok( $@, 'Caught error' ); ok( $@, 'Caught error' );


like( $@, qr/Can't recognize change in changeset\: '\*'/, 'Unknown change' ); like( $@, qr/Can't recognize change in changeset\: '\*'/, 'Unknown change' );
20 changes: 15 additions & 5 deletions t/diff_arrays.t
Expand Up @@ -11,25 +11,35 @@ my @new = qw( john jim james jojo jackie );


diff_arrays( diff_arrays(
\@old, \@new, \@old, \@new,
sub { deleted => sub {
my $val = shift; my $val = shift;
is( $val, 'jarule', 'Goodbye jarule!' ); is( $val, 'jarule', 'Goodbye jarule!' );
}, },
sub { added => sub {
my $val = shift; my $val = shift;
is( $val, 'jojo', 'Hello jojo!'); is( $val, 'jojo', 'Hello jojo!');
}, },
); );


my $empty_list = 0; my $empty_list = 0;
diff_arrays( [], [], sub { $empty_list++ }, sub { $empty_list++ } ); diff_arrays(
[], [],
added => sub { $empty_list++ }, deleted => sub { $empty_list++ },
);
cmp_ok( $empty_list, '==', 0, 'Empty list does not get called' ); cmp_ok( $empty_list, '==', 0, 'Empty list does not get called' );


my $no_change = 0; my $no_change = 0;
diff_arrays( \@old, \@old, sub { $no_change++ }, sub { $no_change++ } ); diff_arrays(
\@old, \@old,
added => sub { $no_change++ }, deleted => sub { $no_change++ },
);
cmp_ok( $no_change, '==', 0, 'No change does not get called' ); cmp_ok( $no_change, '==', 0, 'No change does not get called' );


my $new_count = 0; my $new_count = 0;
diff_arrays( [], \@new, sub { $new_count-- }, sub { $new_count++ } ); diff_arrays(
[],
\@new,
deleted => sub { $new_count-- }, added => sub { $new_count++ },
);
cmp_ok( $new_count, '==', scalar @new, 'New from scratch' ); cmp_ok( $new_count, '==', scalar @new, 'New from scratch' );


14 changes: 8 additions & 6 deletions t/diff_hashes.t
Expand Up @@ -22,17 +22,17 @@ my %new = (


diff_hashes( diff_hashes(
\%old, \%new, \%old, \%new,
sub { deleted => sub {
my ( $name, $val ) = @_; my ( $name, $val ) = @_;
is( $name, 'band', 'Band was removed' ); is( $name, 'band', 'Band was removed' );
is( $val, 'Catharsis', 'Correct band' ); is( $val, 'Catharsis', 'Correct band' );
}, },
sub { added => sub {
my ( $name, $val ) = @_; my ( $name, $val ) = @_;
is( $name, 'artist', 'Artist added' ); is( $name, 'artist', 'Artist added' );
is( $val, 'Michael Jackson', 'Correct artist' ); is( $val, 'Michael Jackson', 'Correct artist' );
}, },
sub { changed => sub {
my ( $name, $before, $after ) = @_; my ( $name, $before, $after ) = @_;
is( $name, 'tvshow', 'Changing tv show' ); is( $name, 'tvshow', 'Changing tv show' );
is( $before, 'Psych', 'Was Psych' ); is( $before, 'Psych', 'Was Psych' );
Expand All @@ -42,19 +42,21 @@ diff_hashes(


my $empty_hash = 0; my $empty_hash = 0;
my $cb = sub { $empty_hash++ }; my $cb = sub { $empty_hash++ };
diff_hashes( {}, {}, $cb, $cb, $cb ); diff_hashes( {}, {}, deleted => $cb, added => $cb, changed => $cb );
cmp_ok( $empty_hash, '==', 0, 'Empty hash does not get called' ); cmp_ok( $empty_hash, '==', 0, 'Empty hash does not get called' );


my $no_change = 0; my $no_change = 0;
$cb = sub { $no_change++ }; $cb = sub { $no_change++ };
diff_hashes( \%old, \%old, $cb, $cb, $cb ); diff_hashes( \%old, \%old, deleted => $cb, added => $cb, changed => $cb );
cmp_ok( $no_change, '==', 0, 'No change does not get called' ); cmp_ok( $no_change, '==', 0, 'No change does not get called' );


my $new_count = 0; my $new_count = 0;
my $change_count = 0; my $change_count = 0;
diff_hashes( diff_hashes(
{}, \%new, {}, \%new,
sub { $new_count-- }, sub { $new_count++ }, sub { $change_count++ }, deleted => sub { $new_count-- },
added => sub { $new_count++ },
changed => sub { $change_count++ },
); );


cmp_ok( $new_count, '==', scalar keys (%new), 'New from scratch' ); cmp_ok( $new_count, '==', scalar keys (%new), 'New from scratch' );
Expand Down
60 changes: 0 additions & 60 deletions t/parameters.t

This file was deleted.

0 comments on commit 9cb2c6b

Please sign in to comment.