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 1784:
=over without closing =back
- Around line 1794:
=over without closing =back