The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::Deep - Complexe Data Structure analysis and manipulation

SYNOPSIS

use Data::Deep;

$dom1=[ \{'toto' => 12}, 33, {o=>5,d=>12}, 'titi' ];

$dom2=[ \{'toto' => 12, E=>3},{d=>12,o=>5}, 'titi' ];

my @patch = compare($dom1, $dom2);

use Data::Deep qw(:DEFAULT :convert :config);

o_complex(1); # deeper analysis results

print join("\n", domPatch2TEXT( compare($dom1,$dom2) ) );

@patch = ( 'add(@0$,@0$%E)=3', 'remove(@1,)=33', 'move(@2,@1)=', 'move(@3,@2)=' );

$dom2 = applyPatch($dom1,@patch);

$h_toto = search $dom1, '@1'

DESCRIPTION

Data::Deep provides search, compare and applyPatch functions which are very usefull for complex Perl Data Structure manipulation (ref, hash or array, array of hash, blessed object and siple scalar). Filehandles and sub functions are not compared (just type is considered).

path definition

First thing to understand is the definition of a path expression, it identify a node in a complex Perl data structure.

Path is composed of the following elements :

   ('%', '<key>') to match a hash table at <key> value
   ('@', <index>) to match an array at specified index value
   ('*', '<glob name>') to match a global reference
   ('|', '<module name>') to match a blessed module reference

   ('$') to match a reference
   ('&') to match a code reference

   ('/') to match a key defined by key() function

   ('=' <value>) to match the leaf node <value>

Modifier <?> can be placed in the path with types to checks :

EX:

   ?%  : match with hash-table content (any key is ok)
   ?@  : match with an array content (any index will match)
   ?=  : any value
   ?*  : any glob type
   ?$  : any reference
   ?=%@      : any value, hash-table or array
   ?%@*|$&=  : everything

Evaluation function : sub{... test with $_ ... } will be executed to match the node EX: sub { /\d{2,}/ } match numbers of minimal size of two

Patch is an operation between two nodes, Patch is composed of : - An action : 'add' for addition of an element from source to destination 'remove' is the suppression from source to destination 'move' if possible the move of a value or Perl Dom 'change' describe the modification of a value - a source path - a destination path

Three patch formats can be use : dom (internal), text (need convertion) and ihm (output format format only) :

   DOM  : Internal dom patch is an hash-table :

        EX: my $patch1 =
                     { action=>'change',
                       path_orig=>['@0','$','%a'],
                       path_dest=>['@0','$','%a'],
                       val_orig=>"toto",
                       val_dest=>"tata"
                     };

   TEXT : text output mode patch could be :

          add(<path source>,<path destination>)=<val dest>
          remove(<path source>,<path destination>)=<val src>
          change(<path source>,<path destination>)=<val src>/=><val dest>
          move(<path source>,<path destination>)

   IHM  : Visual output

Important note :

* search() and path() functions use paths in both format : TEXT EX: '@1%r=432')

  or
      DOM (simple array of elements described above)
            EX: ['@',1,'%','r','=',432]

* applyPath() can use TEXT or DOM patch format in input.

* compare() produce dom patch format in output.

All function prefer the use of dom (internal format) then no convertion is done. Output (user point of view) is text or ihm.

format patches dom can be converted to TEXT : domPatch2TEXT format patches text can be converted to DOM : textPatch2DOM format patches dom can be converted to IHM : domPatch2IHM

See conversion function

Options Methods

zap(<array of path>)

configure nodes to skip (in search or compare) without parameter will return those nodes

o_debug([<debug mode>])

debug mode : 1: set debug mode on 0: set debug mode off undef : return debug mode

o_follow_ref([<follow mode>])

follow mode : 1: follow every reference (default) 0: do not enter into any reference undef: return if reference are followed

o_complex([<complex mode>])

complex mode is used for intelligency complex (EX: elements move in an array) 1: complex mode used in search() & compare() 0: simple analysis (no complex search) undef: return if reference are followed

o_key(<hash of key path>)

key is a search pattern for simplifying search or compare. or a group of pattern for best identification of nodes.

hash of key path:

EX: key( CRC => {regexp=>['%','crc32'], eval=>'{crc32}', priority=>1 }, SZ => {regexp=>['%','sz'), eval=>'{sz}', priority=>2 } )

regexp : path to search in the dom eval : is the perl way to match the node priority : on the same node two ambigues keys are prioritized depth : how many upper node to return from the current match node

Operation Methods

    travel(<dom> [,<visitor function>])

    travel make the visitor function to travel through each node of the <dom>

       <dom>    complexe perl data structure to travel into
       <visitor_fx>()

    Return a list path where the <pattern> argument match with the corresponding node in the <dom> tree data type

    EX:

       travel( {ky=>['l','r','t',124],r=>2}
    
       returns ( [ '%', 'ky', '@' , 3 , '=' , 124 ] )
    search(<tree>, <pattern> [,<max occurrences>])

    search the <pattern> into <tree>

       <tree>      is a complexe perl data structure to search into
       <pattern>   is an array of type description to match
       <max occ.>  optional argument to limit the number of results
                      if undef all results are returned
                      if 1 first one is returned

    Return a list path where the <pattern> argument match with the corresponding node in the <dom> tree data type

    EX: search( {ky=>['l','r','t',124],r=>2} ['?@','=',124])

          Returns ( [ '%', 'ky', '@' , 3 , '=' , 124 ] )
    
    
        search( [5,2,3,{r=>3,h=>5},4,\{r=>4},{r=>5}],
                ['%','r'], 2 )
    
          Returns (['@',3,'%','r'],['@',5,'$','%','r'])
    
    
        search( [5,2,3,{r=>3},4,\3],
                ['?$@%','=',sub {$_ == 3 }],
                2;
    
          Returns (['@',2,'=',3], ['@',3,'%','r','=',3])
    path(<tree>, <paths> [,<depth>])

    gives a list of nodes pointed by <paths> <tree> is the complex perl data structure <paths> is the array reference of paths <depth> is the depth level to return from tree <nb> start counting from the top -<nb> start counting from the leaf 0 return the leaf or check the leaf with '=' or '&' types): * if code give the return of execution * scalar will check the value

    Return a list of nodes reference to the <dom>

    EX:

        $eq_3 = path([5,{a=>3,b=>sub {return 'test'}}],
                      ['@1%a'])
    
        $eq_3 = path([5,{a=>3,b=>sub {return 'test'}}],
                      '@1%a','@1%b')
    
    
        @nodes = path([5,{a=>3,b=>sub {return 'test'}}],
                       ['@1%b&'], # or [['@',1,'%','b','&']]
    
                       0  # return ('test')
                          # -1 or 2 return ( sub { "DUMMY" } )
                          # -2 or 1 get the hash table
                          # -3 get the root tree
                       )]);
    
        @nodes = path([5,{a=>3,b=>sub {return 'test'}}],
                       ['@1%a'], # or [['@',1,'%','b','&']]
    
                       0  # return 3
                          # -1 or 2 get the hash table
                          # -2 or 1 get the root tree
                       )]);
    compare(<node origine>, <node destination>)

    compare nodes from origine to destination nodes are complex perl data structure

    Return a list of <patch in dom format> (empty if node structures are equals)

    EX:

       compare(
               [{r=>new Data::Dumper([5],ui=>54},4],
               [{r=>new Data::Dumper([5,2],ui=>52},4]
              )
    
        return ({ action=>'add',
                  ...
                },
                { action=>'change',
                  ...
                },
                 ...
              )
    applyPatch(<tree>, <patch 1> [, <patch N>] )

    applies the patches to the <tree> (perl data structure) <patch1> [,<patch N> ] is the list of your patches to apply supported patch format should be text or dom types, the patch should a clear description of a modification no '?' modifier or ambiguities)

    Return the modified dom, die if patch are badly formated

    EX: applyPatch([1,2,3],'add(,@4)=4') return [1,2,3,4]

Conversion Methods

    domPatch2TEXT(<patch 1>, <patch 2> [,<patch N>])

    convert a list of patches formatted in perl dom (man perldsc) into a readable text format. Mainly used to convert the compare result (format dom)

    ARGS: a list of <patch in dom format>

    Return a list of patches in TEXT mode

    EX: domPatch2TEXT($patch1) returns 'change(@0$%a,@0$%a)="toto"/=>"tata"'

    domPatch2IHM(<patch 1>, <patch 2> [,<patch N>])

    convert a list of patches in DOM format (internal Data;;Deep format) into a IHM format. Mainly used to convert the compare result (format dom)

    ARGS: a list of <patch in dom format>

    Return a list of patches in IHM mode IHM format is not convertible

    EX: domPatch2IHM($patch1) returns '"toto" changed in "tata" from @0$%a into @0$%a

    textPatch2DOM(<text patch 1>, <text patch 2> [,<text patch N>])

    convert a list of patches formatted in text (readable text format format) to a perl DOM format (man perldsc). Mainly used to convert the compare result (format dom)

    ARGS: a list of <patch in text format>

    Return a list of patches in dom mode

    EX: textPatch2DOM( 'change(@0$%a,@0$%a)="toto"/=>"tata"', 'move(... ' )

    returns ( { action=>'change', path_orig=>['@0','$','%a'], path_dest=>['@0','$','%a'], val_orig=>"toto", val_dest=>"tata" }, { action=>'move', ... });

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 1752:

=over without closing =back

Around line 1762:

=over without closing =back