问题
I am working on a function which should recursively parse through the data structure passed into it and then print it out with indentation. Something like:
indent(foo=>{bar=>'baz'})
should print like:
foo
bar : baz
indent(foo=>[a,b,c=>'d',e])
should print like
foo
a
b
c:d
e
I came across a post here on Stack Overflow with a very similar scenario using depth-first recursion, as well as this page about how to recurse through a Perl data structure.
However, I am unable to follow how the the inner sub works. Also, it does not indent/print for certain scenarios like:
[aa,xx=>'yy',rr]
Output:
aa
xx
yy
rr
This is the code I am trying to work with:
&expand_references2([aa,xx=>'yy',rr]);
sub expand_references2 {
my $indenting = -1;
my $inner; $inner = sub {
my $ref = $_[0];
my $key = $_[1];
$indenting++;
if(ref $ref eq 'ARRAY'){
print ' ' x $indenting;
printf("%s\n",($key) ? $key : '');
$inner->($_) for @{$ref};
}elsif(ref $ref eq 'HASH'){
print ' ' x $indenting;
printf("%s\n",($key) ? $key : '');
for my $k(sort keys %{$ref}){
$inner->($ref->{$k},$k);
}
}else{
if($key){
print ' ' x $indenting,$key,' => ',$ref,"\n";
}else{
print ' ' x $indenting,$ref,"\n";
}
}
$indenting--;
};
$inner->($_) for @_;
}
回答1:
This question is based on a false premise: [a, b, c => 'd', e] will compile only without use strict 'subs' in place, and even then will raise a warning
Unquoted string may clash with future reserved word
It is identical to [ 'a', 'b', 'c', 'd', 'e' ]
The only difference between a fat comma => and an ordinary comma is that it will implicitly quote its first parameter if it is a bareword
You must always use strict and use warnings 'all' at the top of every Perl program you write. It is also wrong to call subroutines with an ampersand character &; that hasn't been good practice since Perl 5 arrived twenty-two years ago. Whatever tutorial you are using to learn Perl you should drop it and find a more recent one
来源:https://stackoverflow.com/questions/36211176/indent-and-recursively-print-data-structure-in-perl