【问题标题】:dereferencing data from multiple hash and array data structure in perl从 perl 中的多个哈希和数组数据结构中取消引用数据
【发布时间】:2012-06-23 12:25:42
【问题描述】:

试图从下面的 DoxyDocs1.pm 文件中的详细 -> 文档 -> 参数 -> 参数 -> 名称中提取数据;还包括提取一些数据的脚本示例,但在提取参数 -> 参数 -> 名称时遇到问题。取消注释评论部分以查看数据。

#!/bin/perl
use Data::Dumper;
use warnings;
require "DoxyDocs1.pm";
print "API Content Analyzer\n";
&GenerateClassInfo($doxydocs->{classes});
sub GenerateClassInfo()
{
    my ($classes) = @_; 
    foreach my $class (@$classes) {
    print "\nClass name is: $class->{name}\n";
    foreach my $pubmeth (@{$class->{public_methods}->{members}}) {
       print "\n" if exists $pubmeth->{name};
       print "\tpublic methods include: $pubmeth->{name}\n";
       my ($key, $pmcontent) = each (@{$pubmeth->{detailed}->{doc}});
       print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
       # foreach my $pmp (@{$pubmeth->{detailed}->{doc}}) {
         # print "\t\t";
         # print Dumper($pmp);
       # }
       print "\t\tkind: $pubmeth->{kind}\n";
       print "\t\ttype: $pubmeth->{type}\n" if exists $pubmeth->{type};
    }
    foreach my $privmeth (@{$class->{private_methods}->{members}}) {
        print "\n" if exists $privmeth->{name};
        print "\tprivate methods include: $privmeth->{name}\n";
        my ($key, $pmcontent) = each (@{$privmeth->{detailed}->{doc}});
        print "\t\tdescription: $pmcontent->{content}\n" if exists $pmcontent->{content};
        # foreach my $info (@{$privmeth->{detailed}->{doc}}) {
         # print "\t\t";
         # print Dumper($info);
        # }
        print "\t\tkind: $privmeth->{kind}\n";
        print "\t\ttype: $privmeth->{type}\n" if exists $privmeth->{type};
    }       
  }
}

DoxyDocs1.pm 文件示例

$doxydocs=
{
  classes => [
    {
     name => 'Panoply::Composite',
     public_methods => {
     members => [
      {
        kind => 'function',
        name => 'addChild',
        virtualness => 'non_virtual',
        protection => 'public',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Add a child to the container '
            },
            params => [
              {
                parameters => [
                  {
                    name => 'child'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'is the child element to add'
                  }
                ]
              }
            ]
          ]
        },
        type => 'void',
        const => 'no',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'child',
            type => 'Ptr'
          }
        ]
      },
      {
        kind => 'function',
        name => 'operator<',
        virtualness => 'non_virtual',
        protection => 'public',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Less than operator'
            },
            {
              type => 'parbreak'
            },
            params => [
              {
                parameters => [
                  {
                    name => 'rval'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'The '
                  },
                  {
                    type => 'url',
                    link => 'classPanoply_1_1Package',
                    content => 'Package'
                  },
                  {
                    type => 'text',
                    content => ' against which we are comparing this one. '
                  }
                ]
              }
            ],
            {
              return => [
                {
                  type => 'text',
                  content => 'true if this.packageID < rval.packageID, false otherwise.'
                }
              ]
            }
          ]
        },
        type => 'bool',
        const => 'yes',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'rval',
            type => 'const Composite &'
          }
        ]
      },
    ]
  },
  private_methods => {
    members => [
      {
        kind => 'function',
        name => 'addChild',
        virtualness => 'virtual',
        protection => 'private',
        static => 'no',
        brief => {},
        detailed => {
          doc => [
            {
              type => 'text',
              content => 'Add a child to the container '
            },
            params => [
              {
                parameters => [
                  {
                    name => 'child'
                  }
                ],
                doc => [
                  {
                    type => 'text',
                    content => 'is the child element to add '
                  }
                ]
              },
              {
                parameters => [
                  {
                    name => 'parent'
                  }
                ],
                doc => [
                  {
                    type => 'parbreak'
                  },
                  {
                    type => 'text',
                    content => 'is this own parent, except in weak pointer format to avoid a memory leak'
                  }
                ]
              }
            ]
          ]
        },
        type => 'virtual void',
        const => 'no',
        volatile => 'no',
        parameters => [
          {
            declaration_name => 'child',
            type => 'Ptr'
          },
          {
            declaration_name => 'parent',
            type => 'Ptr'
          }
        ]
      },
    ]
  },
    }
  ]
 };
1;

【问题讨论】:

    标签: perl perl-data-structures


    【解决方案1】:

    你说你想要

    detailed -> doc -> params -> parameters -> name 
    

    但这缺少许多索引。你想要哪个doc、param和parameters?

    detailed -> doc -> ??? -> params -> ??? -> parameters -> ??? -> name
    

    语法是:

    $member->{detailed}->{doc}->[$i]->{params}->[$j]->{parameters}->[$k]->{name}
    

    或者简称:

    $member->{detailed}{doc}[$i]{params}[$j]{parameters}[$k]{name}
    

    如果你想遍历每个文档、参数、参数,你可以使用:

    my $docs = $member->{detailed}{doc};
    for my $doc (@$docs) {
       my $params = $doc->{params};
       for my $param (@$params) {
          my $parameters = $param->{parameters};
          for my $parameter (@$parameters) {
             ...
          }
       }
    }
    

    (为什么doc是单数而params和parameters是复数???为什么params有参数???)

    【讨论】:

    • 感谢您让我更深入地了解此结构,尽管 {params} 不是哈希引用并且似乎导致了获取参数名称“child”的问题。 DoxyDocs 文件是从 Doxygen 自动生成的,我无法控制它的结构,可能是该应用程序中的一个错误。
    • 这是对数组的引用,我也是这样处理的。
    • 糟糕,我的意思是,Data Dumper 报告以 doc 开头的结构,即 doc 是一个哈希键,其值是对匿名数组的引用。该数组包含 3 个元素:对匿名哈希的引用;字符串“参数”;以及对匿名数组的引用。我可以通过以下方式访问参数子项: $pubmeth->{detailed}->{doc}->[2]->[0]->{parameters}->[0]->{name};可能有更好的方法,我不知道。
    • 我明白了,您指出我误读了doc =&gt; [ { ... }, params =&gt; [ ... ] ]。但这并不奇怪,因为 Data::Dumper 永远不会产生该输出! (请参阅perl -MData::Dumper -e'print Dumper { doc =&gt; [ { a=&gt;1,b=&gt;2 }, params =&gt; [ "..." ] ] }'。)首先显示您实际得到的输出如何?如果您编辑了输出以使其更具可读性,请尝试添加 local $Data::Dumper::Indent = 1;。
    猜你喜欢
    • 1970-01-01
    • 2018-02-25
    • 2016-04-25
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 2016-06-06
    相关资源
    最近更新 更多