Author image Robert Krimen
and 1 contributors


Data::KeyDiff - Diff one set/list against another with a key basis


Version 0.021


    # For each item in the list, the number is the item "key", the letter is the item "data"
    my @A = qw/1a 2b 3c 4d 5e 6f/;
    my @B = qw/5e 1f 2b 3r 4d 7q j n/;

    use Data::KeyDiff qw/diff/;
    diff( \@A, \@B,
        key =>
            sub($item) {
                # Return the leading number from $item

        is_different =>
            sub($a, $b) {
                # Is the letter on $a different from $b?

        is_new =>
            sub($item) {
                # Does $item already have a key?

        # "j" and "n" are new!
        new => sub($element) {
            # Handle a new $element 

        # "7q" was inserted (already had a key)
        insert => sub($element) {
            # $element was "inserted" into @B

        # "1f" and "3r" were updated
        update => sub($element) {
            # $element was "update" in @B

        # "6f" was deleted
        delete => sub($element) {
            # $element was "deleted" in @B
        # "5e", "2b", and "4d" changed rank
        update_rank => sub($element) {
            # $element had it's rank changed in @B


Data::KeyDiff performs a diff-like operation on sets that have unique keys associated with each element. Instead of looking at the whole list, diff looks at each element on a case-by-case basis to see whether it's state or inclusion has changed from the "before" set to the "after" set.


Data::KeyDiff->diff( <before-set>, <after-set>, <configuration> )

Compare the before-set to the after-set. Call handlers in <configuration> as defined.

Besides the before-set and after-set, this method accepts the following:

ignore($item) OPTIONAL

A subroutine that returns true if $item should be ignored (e.g. commented). If an item ignored, the rank counter is not incremented, but the position counter still is.

prepare($item) OPTIONAL

A subroutine that returns a replacement for $item in further processing. Basically, this allows you to preprocess the $item before passing it to key, is_different, etc.


A subroutine that returns true if $item is "new" and so doesn't already have a key. Note, this subroutine is not run on the before-set (every item in that set should already have a key).


A subroutine that returns the key of $item.

is_different($before_item, $after_item, $before_element, $after_element)
compare($before_item, $after_item, $before_element, $after_element)

A subroutine that returns true if $before_item is different from $after_item.

new($element) OPTIONAL

Called for each new $element

insert($element) OPTIONAL

Called for each $element that should be inserted

update($element) OPTIONAL

Called for each $element that should be updated

update_rank($element) OPTIONAL

Called for each $element that is otherwise the same, but has a different rank

delete($element) OPTIONAL

Called for each $element that should be deleted


diff( ... )

Same syntax as above. See above for more information.


Robert Krimen, <rkrimen at>


Please report any bugs or feature requests to bug-data-keydiff at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


You can find documentation for this module with the perldoc command.

    perldoc Data::KeyDiff

You can also look for information at:



Copyright 2007 Robert Krimen, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.