Data-Structure-Util

 view release on metacpan or  search on metacpan

lib/Data/Structure/Util.pm  view on Meta::CPAN


    # get the objects in the data structure
    my $objects_arrayref = get_blessed( $data );

    # unbless all objects
    unbless( $data );

    if ( has_circular_ref( $data ) ) {
        print "Removing circular ref!\n";
        circular_off( $data );
    }

    # convert back to latin1 if needed and possible
    utf8_off( $data ) if defined has_utf8( $data );

=head1 DESCRIPTION

C<Data::Structure::Util> is a toolbox to manipulate the data inside a
data structure. It can process an entire tree and perform the operation
requested on each appropriate element.

For example: It can transform all strings within a data structure to
utf8 or transform any utf8 string back to the default encoding. It can
remove the blessing on any reference. It can collect all the objects or
detect if there is a circular reference.

It is written in C for decent speed.

=head1 FUNCTIONS

All Data::Structure::Util functions operate on a whole tree. If you pass
them a simple scalar then they will operate on that one scalar. However,
if you pass them a reference to a hash, array, or scalar then they will
iterate though that structure and apply the manipulation to all
elements, and in turn if they are references to hashes, arrays or
scalars to all their elements and so on, recursively.

For speed reasons all manipulations that alter the data structure do in-
place manipulation meaning that rather than returning an altered copy of
the data structure the passed data structure which has been altered.

=head2 Manipulating Data Structures

=over 4

=item has_circular_ref($ref)

This function detects if the passed data structure has a circular
reference, that is to say if it is possible by following references
contained in the structure to return to a part of the data structure you
have already visited. Data structures that have circular references will
not be automatically reclaimed by Perl's garbage collector.

If a circular reference is detected the function returns a reference
to an element within circuit, otherwise the function will return a
false value.

If the version of perl that you are using supports weak references then
any weak references found within the data structure will not be
traversed, meaning that circular references that have had links
successfully weakened will not be returned by this function.

=item circular_off($ref)

Detects circular references in $ref (as above) and weakens a link in
each so that they can be properly garbage collected when no external
references to the data structure are left.

This means that one (or more) of the references in the data structure
will be told that the should not count towards reference counting. You
should be aware that if you later modify the data structure and leave
parts of it only 'accessible' via weakened references that those parts
of the data structure will be immediately garbage collected as the
weakened references will not be strong enough to maintain the connection
on their own.

The number of references weakened is returned.

=item get_refs($ref)

Examine the data structure and return a reference to flat array that
contains one copy of every reference in the data structure you passed.

For example:

    my $foo = {
        first  => [ "inner", "array", { inmost => "hash" } ],
        second => \"refed scalar",
    };

    use Data::Dumper;
    # tell Data::Dumper to show nodes multiple times
    $Data::Dumper::Deepcopy = 1;
    print Dumper get_refs( $foo );

    $VAR1 = [
        { 'inmost' => 'hash' },
        [ 'inner', 'array', { 'inmost' => 'hash' } ],
        \'refed scalar',
        {
            'first'  => [ 'inner', { 'inmost' => 'hash' }, 'array' ],
            'second' => \'refed scalar'
        }
    ];

As you can see, the data structure is traversed depth first, so the
top most references should be the last elements of the array.  See
L<get_blessed($ref)> below for a similar function for blessed objects.

=item signature($ref)

Returns a md5 of the passed data structure.  Any change at all to the
data structure will cause a different md5 to be returned.

The function examines the structure, addresses, value types and flags
to generate the signature, meaning that even data structures that
would look identical when dumped with Data::Dumper produce different
signatures:

    $ref1 = { key1 => [] };

    $ref2 = $ref1;
    $ref2->{key1} = [];

    # this produces the same result, as they look the same
    # even though they are different data structures
    use Data::Dumper;
    use Digest::MD5 qw(md5_hex);
    print md5_hex( Dumper( $ref1 ) ), " ", md5_hex( Dumper( $ref2 ) ), "\n";
    # cb55d41da284a5869a0401bb65ab74c1 cb55d41da284a5869a0401bb65ab74c1

    # this produces differing results
    use Data::Structure::Util qw(signature);
    print signature( $ref1 ), " ", signature( $ref2 ), "\n";
    # 5d20c5e81a53b2be90521167aefed9db 8b4cba2cbae0fec4bab263e9866d3911

=back



( run in 0.928 second using v1.01-cache-2.11-cpan-39bf76dae61 )