2022 twenty-four merry days of Perl Feed

What did Santa forget?

Value::Diff - 2022-12-09

Santa is about ready to start his yearly trip around the world! But does he really have everything?

It would be silly not to deliver a present to someone who has been trying the whole year to be nice. Luckily, to avoid such a blunder, he made a list beforehand:

my %santas_list = (
    presents => [
        'for Rob',
        'for Lisa',
        'for Brian',
        'for Amy',
        'for Chris',
        'for Larry',
        'for Scott',
        'for Sabina',
        'for Shirley',
        'for Richard',
        'for Amy',
    ],
    other => [
        'candy canes',
        'fireplace break-in tool',
        'cookies degustation kit',
    ],
);

Now all he needs to do is compare it to the list of things he packed. He asked the elves how should he do it, and they suggested giving a try to recently released module Value::Diff:

my %santas_package = (
    presents => [
        'for Richard',
        'for Rob',
        'for Lisa',
        'for Larry',
        'for Brian',
        'for Scott',
        'for Sabina',
        'for Shirley',
        'for Amy',
        'for Chris',
    ],
    other => [
        'cookies degustation kit',
        'candy canes',
        'sleigh repair tool',
        'fireplace break-in tool',
    ],
);

use v5.36;
use Value::Diff;
use Data::Dumper;

if (diff(\%santas_list, \%santas_package, \my $missing)) {
    say 'looks like you forgot something: ' . Dumper($missing);
}
else {
    say 'all looks good...';
}

The diff function used here recursively compares its two first arguments, creating a new data structure which contains the differences. It returns a true value if the arguments are not equal, and the diff is put into $missing.

With this program, Santa got his answer:

    looks like you forgot something: $VAR1 = {
              'presents' => [
                              'for Amy'
                            ]
            };

Right! There are two Amys on the list, and he only has a present for one. Of course he doesn't need last names, he simply distinguishes them by their first names alone.

Rudolph liked the new module, but since he's a reindeer he has major difficulties typing on the keyboard. He read the documentation thoroughly instead and noticed that the module only finds missing elements, not the excessive ones! So Santa reversed the order of values and tried again:

if (diff(\%santas_package, \%santas_list, \my $excess)) {
    say 'looks like you have something extra: ' . Dumper($excess);
}
else {
    say 'all looks very good now...';
}

diff function tries to find a Perl data structure which describes the patch for the second value to be equal to the first one. With arguments order reversed in the second call, Santa could see the full picture:

    looks like you forgot something: $VAR1 = {
              'presents' => [
                              'for Amy'
                            ]
            };
    looks like you have something extra: $VAR1 = {
              'other' => [
                           'sleigh repair tool'
                         ]
            };

Well of course he doesn't need that, he can use magic instead!

It was getting late and the fireplace started to flicker out. Happy with his program, Santa put his laptop away, stood up and picked up his presents bag. Ho Ho Ho, it's time for the delivery!

Gravatar Image This article contributed by: Bartosz Jarzyna <bbrtj.pro@gmail.com>