in reply to Re: Augmenting and reducing data structures
in thread Augmenting and reducing data structures

The devil is -like so often - in the details for edge cases:

Ignore? Warning? Exception and/or Dieing?

The combination of all error cases will make it hard to find a ready to use module whose customization is easier than a new implementation.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

  • Comment on Re^2: Augmenting and reducing data structures

Replies are listed 'Best First'.
Re^3: Augmenting and reducing data structures
by sciurius (Beadle) on Apr 23, 2021 at 12:02 UTC

    My question originates from a large software project that has a complex configuration structure.

    Something similar to:

    # cfg1 $config = { "common" => { debug => 1, logfile => "/var/log/project.log", path => "/opt/projects/bin", }, "project_1" => { name => "Project 1", tasks => [ { name => "Prepare", program => "p1prep", arguments => [ "--init", '--default' ], logfile => "/var/log/p1prep.log", }, { name => "Work", program => "p1", arguments => [ "--collect" ], logfile => "/var/log/p1.log", env => { DISPLAY => undef, }, }, { name => "Wrapup", program => "signal", arguments => [ "p1", "finished" ], }, ] }, "project_2" => { "and" => [ "so", "on", "..." ], }, };

    A particular customer could supply her own config, e.g.

    # cfg2 $config = { "common" => { debug => 0, logfile => "/var/log/project.log", path => "/opt/projects/bin", }, "project_1" => { name => "Project 1", tasks => [ { name => "Prepare", program => "p1prep", arguments => [ "--init", '--default' ], logfile => "/var/log/p1prep.log", }, { name => "Work", program => "p1", arguments => [ "--collect", "--brief" ], logfile => "/var/log/p1.log", env => { DISPLAY => undef, }, }, { name => "Wrapup", program => "signal", arguments => [ "p1", "finished" ], }, ] }, "project_2" => { "and" => [ "so", "on", "..." ], }, };

    But instead of supplying a full config, it suffices to supply a smaller set of modifications:

    # cfgaug $config = { "common" => { debug => 0 }, "project_1" => { tasks => [ { name => "Prepare" }, { name => "Work", arguments => [ "--collect", "--brief" ], }, { name => "Wrapup" }, ] }, };

    Applying #cfgaug to #cfg1 will result in #cfg2.

    Since several of these augmentations are possible, the need arises to produce a single 'delta' that augments the base configuration #cfg1 to the actual state.

      1. it seems you confused cfgaug with cfgdelta following your own terminology in the OP
      2. you've added more complex and fuzzy requirements by altering arrays:

        [ "--collect" ] becomes [ "--collect", "--brief" ],

      3. you haven't told us at all how to treat arrays ...

        e.g. do they represent sets were the order doesn't matter?

      You've been provided with two solutions, Hippo mentioned modules I've sketched an algorithm.

      I think it's time for you to wet your feet and come up with an SSCCE plus test suite for this special kind of data.

      Unfortunately we are not telepathic, we can't help you with fuzzy requirements of an alien cfg format.

      I strongly recommend you implementing the recursive walker (many examples in the archives) which dives into your data and handles scalars, arrays and hashes by type.

      Then you play around and handle special edge cases AND semantics, like one array is supposed to be a set, the other one is ordered an so on ...

      That way you'll also get at least a validator for your "user supplied" cfg-format.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        There are a couple of additional constraints that make the tast easier:

        • The corresponding data types of the old and new structures match;
        • There are no undefined values involved.

        Nevertheless further research has show that there are a lot of edge cases that make the task complicated.

        I'm investigating the Struct::Diff approach, as well as several other suggestions from this thread. Thanks a lot for the input!

Re^3: Augmenting and reducing data structures (test)
by LanX (Saint) on Apr 22, 2021 at 17:15 UTC
      Maybe a message from someone else is more lucky?

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        Am I talking to myself?

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      trying again, deleted some in my inbox, maybe there is a limit at 128

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      I never get replies from PerlMonks... I thought that was a feature :( .