I like the following. It can even clear the variable you pass as the arg to clean().
sub clean { our $node; local *node = \$_[0]; # Alias return if !defined($node); my $reftype = ref($node); return if !$reftype; if ($reftype eq 'REF' || $reftype eq 'SCALAR') { clean($$node); $node = undef if !defined($$node); } elsif ($reftype eq 'ARRAY') { clean($_) for @$node; @$node = grep defined, @$node; $node = undef if !@$node; } elsif ($reftype eq 'HASH') { clean($_) for values(%$node); delete @{$node}{ grep !defined($node->{$_}), keys(%$node) }; $node = undef if !keys(%$node); } }
For each reference type, it cleans each item in the referenced container, cleans the referenced variable, then cleans the reference itself. Each of these steps involves syntax that's specific to the type of reference, so they can't be combined.
Tester:
use strict; use warnings; use Data::Dumper qw( Dumper ); sub dumper { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; return Dumper($_[0]); } for ( [ [1], [], {1 => 2, 2 =>{} } ], [ undef, [ undef ], { x => undef }, \undef, \\\undef ], ) { my $d = $_; print(dumper($d), "\n"); clean($d); print(dumper($d), "\n"); print("\n"); }
[[1],[],{1 => 2,2 => {}}] [[1],{1 => 2}] [undef,[undef],{"x" => undef},\undef,\\$VAR1->[3]] undef
Update: Replaced a "!" that wandered off.
In reply to Re: Perl task function
by ikegami
in thread Perl task function
by usr345
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |