Perl中的缩进和递归打印数据结构

Perl中的缩进和递归打印数据结构,perl,recursion,Perl,Recursion,我正在研究一个函数,它应该递归地解析传递给它的数据结构,然后用缩进打印出来。比如: 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 我在这里遇到了一个使用深度优先递归的类似场景的堆栈溢出,以及关于如何通过Perl数据结构递归的场景 但是,我无法理解内部子组件是如

我正在研究一个函数,它应该递归地解析传递给它的数据结构,然后用缩进打印出来。比如:

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
我在这里遇到了一个使用深度优先递归的类似场景的堆栈溢出,以及关于如何通过Perl数据结构递归的场景

但是,我无法理解内部子组件是如何工作的。此外,它不会在某些情况下缩进/打印,例如:

[aa,xx=>'yy',rr]
Output:
  aa
  xx
  yy
  rr
这是我尝试使用的代码:

&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 @_;
}

这个问题基于一个错误的前提:
[a,b,c=>'d',e]
只会在没有
使用严格的'subs'
的情况下编译,即使这样也会发出警告

不带引号的字符串可能与将来的保留字冲突

它与
['a','b','c','d','e']相同。

胖逗号
=>
和普通逗号之间的唯一区别在于,如果第一个参数是空字,它将隐式引用第一个参数


在编写的每个Perl程序的顶部,必须始终
使用strict
使用警告'all'
。使用符号和字符调用子例程也是错误的;自从22年前Perl5问世以来,这就不是一个好的实践。无论您使用什么教程来学习Perl,您都应该放弃它,找到一个最近的教程

这个问题基于一个错误的前提<代码>[a,b,c=>'d',e]将只编译没有
的文件,使用严格的“subs”
将发出警告,即使这样,不带引号的字符串也可能与将来的保留字冲突。它与
['a','b','c','d','e']相同
=>
和普通逗号之间的唯一区别在于,如果第一个参数是空字,它会简单地引用第一个参数。您必须始终
在编写的每个Perl程序的顶部使用strict
使用warnings'all'
。使用符号和字符调用子例程也是错误的;自从22年前Perl5问世以来,这就不是一个好的实践。无论您使用什么教程来学习Perl,您都应该放弃它,找到一个更新的教程Borodin:谢谢,您是对的。它确实把[a,b,c=>d',e ]看成[ a’,b,'c','d','e'),没有缩进。而且,它没有使用严格的subs,这就是为什么它编译并预测结果,因为bcd eData::Dumper正是这样做的;您可以使用它来显示输出应该是什么样子
perl-MData::Dumper-e'print Dumper[aa,xx=>“yy”,rr]
请不要在您的帖子中添加更多问题。如果你有一个新问题,那么你应该提出一个新问题