stevieb has asked for the wisdom of the Perl Monks concerning the following question:

Hey all,

Is there an is_deeply()-esque function somewhere that does not belong to a test module? It works perfectly for what I'm trying to do, but I can't get the test output to redirect properly, and it interferes with my actual unit tests.

I've put some code I was toying with for testing below, just because it's the right thing to do on PerlMonks when asking a question. It's awful for many reasons, fails unsafely, and uses experimental features. I'm sure things will click together when I look at it tomorrow, but the ol' brain has given up thinking with it being Friday afternoon and all.

In the code, I've shortened certain things to fit reasonably nicely... s/current/c/, s/previous/p/. The structure is a hash ref that contains either strings or arrays.

self->{cache_safe} = 1; my @unsafe_cache_params = qw(file extensions include exclude search); my $c = $self->{params}; my $p = $self->{p_run_config}; { no warnings 'uninitialized'; for (@unsafe_cache_params){ if (defined $c->{$_} || defined $p->{$_}){ if (ref $c->{$_} eq 'ARRAY' || ref $p->{$_} eq 'ARRAY'){ if (! (@{$c->{$_}} ~~ @{$p->{$_}})){ $self->{cache_safe} = 0; last; } } elsif ($c->{$_} ne $p->{$_}){ $self->{cache_safe} = 0; last; } } } }

All I need to do is verify whether certain portions of the data structure that is the configuration of the last run are the same as this run.

Replies are listed 'Best First'.
Re: Is there an is_deeply() outside of Test::More?
by stevieb (Canon) on Aug 14, 2015 at 21:00 UTC

    Seems every time I ask a question here, I end up finding a workable solution. It must be just the fact I'm speaking 'out loud' about the issue. The following seems to do what I'm after:

    #!/usr/bin/perl use warnings; use strict; use Data::Compare; my %h = (a => [1, 2, 3], b => [1, 2], c => 3); my %x = (a => [1, 2], b => [1, 2], c => 3); for (keys %h){ my $y = Compare($h{$_}, $x{$_}); print "$_ :: $y\n"; } __END__ $ ./comp.pl a :: 0 b :: 1 c :: 1

    As always, I'm still absolutely open to suggestions.

      It must be just the fact I'm speaking 'out loud' about the issue.

      It has a couple names, including Rubber duck debugging. It's used by quite a few monks. I use a platypus, a Motoko Kusanagi figurine, various Papo dinosaurs, etc.

        It has a couple names, including Rubber duck debugging.

        I force a co-worker to listen, preferably one not working on my project. Or my wife. Or my neighbour. Or whoever is nearby. Simply because they can ask questions. In almost all cases, when starting to explaining the problem did not help, the problem is a little detail that I did not explained well enough, simply because I did not understand it well enough, or because I misread that detail.

        Another trick that really helps me is to stop working on the problem. Lock the computer, leave the room or even the building. Take a short walk (5 min). Think about something completely different. Go through your shopping list, watch the stupid dog next door freaking out, or use the restroom. Whatever helps to get your brain out of "job mode" and to get some unrelated input. Go back to the computer and rethink your problem.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        That's awesome Your Mother, thanks. I've never heard of that before :)

        I was a bit afraid I was leaning into the XY Problem, but consistently when I ask a question of the fellow Monks, I inevitably come up with a solution. Perhaps not the best solution, but I learn something new either way, then usually more experienced Monks provide far better solutions... which is why I try to describe the problem, along with what I've currently got.

        Cheers,

        -stevieb

      I've had good experiences using Data::Compare in the past. One of the reviews notes that it is quite a bit slower than is_deeply(), but I've never used it on anything especially large.

        Yeah... and the following code looks a hell of a lot better than before...

        # set up for caching my @unsafe_cache_params = qw(file extensions include exclude search); my $current = $self->{params}; my $previous = $self->{previous_run_config}; $self->{cache_safe} = 0; for (@unsafe_cache_params){ $self->{cache_safe} = Compare($current->{$_}, $previous->{$_}); last if ! $self->{cache_safe}; }