Michael Anton Dines Zedeler > Data-Dmap-0.08 > Data::Dmap

Download:
Data-Dmap-0.08.tar.gz

Dependencies

Annotate this POD

CPAN RT

New  2
Open  0
View/Report Bugs
Module Version: 0.08   Source  

NAME ^

Data::Dmap - just like map, but on deep data structures

VERSION ^

Version 0.08.

SYNOPSIS ^

This module provides the single function dmap which carries out a map-like operation on deep data structures.

    use Data::Dmap;

    my $foo = {
        cars => [ 'ford', 'opel', 'BMW' ],
        birds => [ 'cuckatoo', 'ostrich', 'frigate' ],
        handler => sub { print "barf\n" }
    };

    # This removes all keys named 'cars'    
    my($bar) = dmap { delete $_->{cars} if ref eq 'HASH'; $_ } $foo;

    # This replaces arrays with the number of elements they contains
    my($other) = dmap { $_ = scalar @$_ if ref eq 'ARRAY'; $_ } $foo;

    use Data::Dumper;
    print Dumper $other;
    #
    # Prints
    # {
    #    birds => 3,
    #    handler => sub { "DUMMY" }
    # }
    # (Data::Dumper doesn't dump subs)

    $other->{handler}->();
    # Prints
    # barf

EXPORTS ^

dmap (always exported) - the dmap function that does deep in-place mapping
cut (optional) - a function for stopping recursion.

SUBROUTINES ^

dmap

This function works like map - it takes an expression followed by a list, evaluates the expression on each member of the list and returns the result.

The only difference is that any references returned by the expression will also be traversed and passed to the expression once again, thus making it possible to make deep traversal of any data structure.

Objects (references blessed to something) are just traversed as if they weren't blessed.

Examples

Delete all hash references

    use Data::Dmap;
    use Data::Dump 'pp';
    
    pp dmap { return $_ unless ref eq 'HASH'; return; } 1, 'foo', [ { a => 1 }, 2];
    
    # Prints:
    # (1, "foo", [2])

Delete every odd number

    use Data::Dmap;
    use Data::Dump 'pp';
    
    pp dmap { return if $_ % 2; $_ } [ 1 .. 10 ];

    # Prints:
    # [2, 4, 6, 8, 10]

Replace all hash refs with some $object of class thingy.

    use Data::Dmap;
    use Data::Dump 'pp';
    
    pp dmap { return bless $_, 'thingy' if ref eq 'HASH'; $_ } [ 1, "hello", { a => 1 } ];
    
    # Prints:
    # [1, "hello", bless({ a => 1 }, "thingy")]

dmap understands what you want, if you return nothing (as opposed to undef) when evaluating the expression for a hash key:

    use Data::Dmap;
    use Data::Dump 'pp;

    my $characters = { main => 'pooh', secondary => 'piglet' };
    pp dmap { return if $_ eq "piglet"; $_ } $characters;
    
    # Prints:
    # { main => "pooh" }

Because the output from the expression is being traversed, you can use dmap to generate data structures:

    use Data::Dmap;
    use Data::Dump 'pp';
    
    my $height = 3;
    pp dmap { if(ref eq 'HASH' and $height--) { $_->{a} = {height => $height} } $_ } {};
    
    # Prints:
    # {
    #     a => {
    #         a => {
    #             a => { 
    #                 height => 0
    #             },
    #             height => 1
    #         },
    #         height => 2
    #     }
    # }
    # (My own formatting above.)

cut

The cut routine stops recursion at any point and returns any data as it is in place of the current node.

Examples

    use Data::Dmap 'cut';
    use Data::Dump 'pp';
    
    my $deep = {
        level => 1,
        data  => {
            level => 2,
            data => {
                level => 3
            }
        }
    };
    
    pp dmap { cut('stop') if ref eq 'HASH' and $_->{level} == 2} $deep;

    # Prints:
    #
    # { data => { data => "stop", level => 2 }, level => 1 }

AUTHOR ^

Michael Zedeler, <michael@zedeler.dk>

BUGS ^

If you find a bug, please consider helping to fix the bug by doing this:

Bugs and feature requests can be reported through the web interface at http://github.com/mzedeler/Data-Dmap/issues. I may not be notified, so send me a mail too.

SUPPORT ^

You can find documentation for this module with the perldoc command.

    perldoc Data::Dmap

You can also look for information at:

SEE ALSO ^

Data::Rmap, Data::Visitor, Data::Transformer, Data::Visitor, Data::Walk.

TODO ^

Some kind of option making it possible to traverse objects with Class::MOP metaclasses, so we can avoid breaking encapsulation.
Options to provide more information about the current node to the callback handler, such as path, depth and data types. Should not affect performance if not used.

LICENSE AND COPYRIGHT ^

Copyright 2010 Michael Zedeler.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

syntax highlighting: