【问题标题】:Perl - Return hash of objects as single object from a classPerl - 将对象的哈希作为类中的单个对象返回
【发布时间】:2017-11-02 08:25:48
【问题描述】:

一般来说,perl 对象是散列、数组、标量、文件句柄等数据结构。

我正在考虑一种情况,即 perl 模块可以将对象的散列(每个对象作为散列)作为单个对象返回。请考虑以下情况。

我有一个包含多个文档的 YAML 文件。 (或具有多组相同配置节点的 XML)。我需要一个 perl 模块,我可以将这个 YAML 文件作为输入传递,并接收对象的散列(每个对象对应于 YAML 文件中的一个文档)。

YAML

---
mykey: 1
myname: John
---
mykey: 2
myname: Doe
----
mykey: 3
myname: Chris
...

上面的 YAML 文件中有 3 个文档。让我们考虑这将是输入文件。

我想写一些类似下面的东西并访问对象的哈希。

SimpleParser.pl

use strict;
use warnings;
use YAMLParser;
my %objHashRef = YAMLParser->new('input.yml');

print keys %objHashRef;    #print keys for each objects
print values %objHashRef;  #print hash reference of each object

my $thirdObjectName = $objHashRef{3}->get_name();
print $thirdObjectName;    #this prints 'Chris'

要实现这种行为,需要在 perl 模块文件中进行哪些修改,类似于以下内容?

YAMLParser.pm

use strict;
use warnings;
sub new {
    my ($class) = shift;
    my $self = {
         inputFile => shift,
         name => shift
    };
    bless $self, $class;
    return $self;
}

sub set_name {
    $self->{name} = $name;
}

sub get_name {
    my ($self) = @_;
    return $self->{name};
} 
1;

下面是一个示例 YAML 解析 sn-p,如果需要,可以提供帮助。

my @list;
my $myname;
my $i = 0;
my @conf = LoadFile('input.yml');   #returns array of reference to each document in the YAML file
my $config = \@conf;      #Returns reference to an array

foreach ( @conf ) {
    $list[$i] = $config->[$i]->{mykey};
    $objHash{$list[$i]} = YAMLParser->new();
    $myname = $config->[$i]->{myname};
    $objHash{$list[$i]}->setMyname($myname);
    my $host = $objHash{$list[$i]}->getMyname();
    $i++;
}

请告诉我你的想法。

【问题讨论】:

  • 为了澄清您的问题,您想知道如何从您的new 方法返回哈希而不是哈希引用?
  • 不,我隐含的意思是 hashref 指向对象的散列,而不是 hashref 指向散列。现在清除吗?
  • 不太清楚...最后一个sn-p代码有什么问题?那就是构建一个包含对象的哈希。

标签: perl oop object hashmap


【解决方案1】:

只需将结构存储到以mykey 为键的哈希中即可。我使用了map,但也可以使用for循环:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{
    package YAMLHash;
    use YAML qw{ LoadFile };
    sub new {
        my ($class, $file) = @_;
        my %hash = map { $_->{mykey} => $_ } LoadFile($file);
        bless \%hash, $class
    }
}


my $obj = 'YAMLHash'->new('1.yaml');

say keys %$obj;
say values %$obj;

my $third_object_name = $obj->{3}{myname};
print $third_object_name;    #this prints 'Chris'

注意$obj->{3} 不是第三个对象。就是mykey为3的对象。

【讨论】:

    【解决方案2】:

    CPAN 上有许多模块,它们很乐意从散列中创建一个对象(见鬼,我什至写了一个:Hash::Wrap)。如果你想递归地将对象范式应用到 YAML 文档的嵌套部分,我最喜欢的是Hash::AsObject。请参阅Hash::Wrap 了解更全面的类似模块列表。

    这里有一些代码。它返回一个 list 对象,而不是一个 hash 对象,但修复它非常简单。

    use 5.010;
    
    use strict;
    use warnings;
    
    use Hash::AsObject;
    use YAML 'Load';
    
    
    my $yaml = do { local $/ = undef;
                    <DATA>
                };
    
    my @objs = map { Hash::AsObject->new( $_ ) } Load( $yaml );
    
    say " Name: ", $objs[0]->myname;
    $objs[0]->myname( "Frank" );
    say " Name: ", $objs[0]->myname;
    
    __DATA__
    
    ---
    mykey: 1
    myname: John
    ---
    mykey: 2
    myname: Doe
    ---
    mykey: 3
    myname: Chris
    

    还有输出:

     Name: John
     Name::Frank
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 2011-01-17
      相关资源
      最近更新 更多