Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I merge two complex data structures in Perl?
    primarykey
    data
    text
    <p>I have a config file formatted as JSON that I need to load into Perl and then partially override/extend with new settings loaded from a separate JSON file. The particular settings that might be added/changed vary, so I want to make this override as flexible as I can.</p> <p>My plan is to merge a new partial config into the existing full config object - either in JSON or as a Perl nested data structure after using decode_json. That conversion works fine.</p> <p>Is there a simple and efficient way to do this in Perl, short of recursively walking through my complex data structure and making a lot of specific comparisons? I've looked into Hash::Merge and it is mangling my data. The issue seems to be that it looks at high level key/value pairs ("config" or "bookToolbar" below) and overrides the full key/value pair at that high level. What I want is to search depth-first and override the most specific values that it can, while keeping the other key/value pairs from the original.</p> <p>For example, here is a "full" config:</p> <pre><code>{ "config" : { "bookToolbar" : { "highlights" : { "enabled" : false }, "bookmark" : { "enabled" : false } }, "pageAspectRatio" : { "width" : "432", "height" : "648" }, "highlighter" : { "sharedColor" : "#000000", "colors" : [ "#ffff00" ] } "mainMenu" : { "index" : { "dataPath" : "data/index/", "enabled" : false }, "media" : { "dataPath" : "data/media.xml", "enabled" : false }, "toc" : { "dataPath" : "data/toc.xml" }, "glossary" : { "audioPath" : "audio/glossary/", "dataPath" : "data/glossary.xml", "imagePath" : "img/glossary/", "enabled" : false } } }, "pagelist" : [{ "hasOnPageNotes" : true, "pageName" : "cover", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "cover" }, { "hasOnPageNotes" : true, "pageName" : "1", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "1" } ] } </code></pre> <p>And here is the data I want to use to partially override/extend the above:</p> <pre><code>{ "config" : { "bookToolbar" : { "bookmark" : { "enabled" : true }, "help" : { "data" : { "url" : "aGreatHelpFile.html" }, "enabled" : true }, "links" : { "enabled" : true } } }, "pagelist" : [{ "hasOnPageNotes" : true, "pageName" : "2", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "2" } ] } </code></pre> <p>My desired output would be:</p> <pre><code>{ "config" : { "bookToolbar" : { "highlights" : { "enabled" : false }, "help" : { "data" : { "url" : "aGreatHelpFile.html" }, "enabled" : true }, "bookmark" : { "enabled" : true } "links" : { "enabled" : false } }, "pageAspectRatio" : { "width" : "432", "height" : "648" }, "highlighter" : { "sharedColor" : "#000000", "colors" : [ "#ffff00" ] }, "mainMenu" : { "index" : { "dataPath" : "data/index/", "enabled" : false }, "media" : { "dataPath" : "data/media.xml", "enabled" : false }, "toc" : { "dataPath" : "data/toc.xml" }, "glossary" : { "audioPath" : "audio/glossary/", "dataPath" : "data/glossary.xml", "imagePath" : "img/glossary/", "enabled" : false } } }, "pagelist" : [{ "hasOnPageNotes" : true, "pageName" : "cover", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "cover" }, { "hasOnPageNotes" : true, "pageName" : "1", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "1" }, { "hasOnPageNotes" : true, "pageName" : "2", "hasScreenReader" : false, "hasTextMarkup" : true, "hasLinks" : false, "pageId" : "2" } ] } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload