Отступ и рекурсивная печать структуры данных в 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 @_;
}

1 ответ

Решение

Этот вопрос основан на ложной предпосылке: [a, b, c => 'd', e] будет компилировать только без use strict 'subs' на месте, и даже тогда будет предупреждать

Строка без кавычек может конфликтовать с будущим зарезервированным словом

Это идентично [ 'a', 'b', 'c', 'd', 'e' ]

Единственная разница между жирной запятой => и обычная запятая в том, что она будет неявно заключать в кавычки свой первый параметр, если это голое слово

Вы должны всегда use strict а также use warnings 'all' в верхней части каждой Perl-программы, которую вы пишете. Также неправильно вызывать подпрограммы с символом амперсанда &; это не было хорошей практикой с тех пор, как Perl 5 появился двадцать два года назад. Какой бы учебник вы не использовали для изучения Perl, вы должны оставить его и найти более новый.

Другие вопросы по тегам